PHP Roundtable #36

Hoszt:

Naményi Dávid (@NamenyiDavid)

Sági-Kazár Márk (@sagikazarmark)

Kocsis Máté (@kocsismate90)

Támogatónk:

  • A modern PHP fejlesztői környezet

  • Hobbi infrastruktúra

Mai témák

The modern PHP development environment

What is a good dev env like?

  • Intuitive

  • Fast & easy-to-install

  • Platform-independent

  • Shortens the feedback loop

Level 0: Choose a decent IDE

PhpStorm

Must have plugin:

PHP Inspections

  • Multiple cursors
  • Intentions
  • Debugger

  • VCS support

  • Terminal

  • Database tools

  • Other plugins for

    • Composer

    • Twig/Blade

    • Spelling

    • etc.

Plus...

Level 0.5: .editorconfig

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.tf]
indent_size = 2

Level 1: Install script

#!/usr/bin/env bash

# Installing Zsh
brew install zsh

# Installing iTerm2
brew cask install iterm2

# Installing Chrome
brew cask install google-chrome

# Installing Git & GitHub Desktop
brew install git
brew cask install github

# Installing GPG Suite
brew cask install gpg-suite

# Installing PHP..."
brew tap homebrew/dupes
brew tap homebrew/versions
brew tap homebrew/homebrew-php
brew install php73

Level 1.5: Release script

Last tag: 4.0.0-beta1
Which version do you wish to release? 4.0.0-beta2

CHECKLIST:
    - Update read me
    - Update change log
    - Run the tests
    - Check integration statuses

Do you wish to create the tag '4.0.0-beta2' (y/n)? y

VALIDATING...
    - The CHANGELOG.md file has been validated successfully

SUCCESSFULLY CREATED TAG: 4.0.0-beta2.

Do you wish to publish the tag '4.0.0-beta2' (y/n)?

Level 2: Docker

A typical Read Me with Docker:

#!/usr/bin/env bash

# Install Docker Desktop
brew cask install docker

# Run the project
docker-compose up

# Done

Level 3: Makefile

.PHONY: up

up:
	docker-compose stop --timeout=2 && docker-compose up -d

down:
	docker-compose stop --timeout=2

phpstan:
	docker-compose run --rm php /bin/bash -c "cd /var/www && ./vendor/bin/phpstan analyse --level 7 src"

cs:
	docker-compose run --rm php /var/www/vendor/bin/phpcs --standard=/var/www/phpcs.xml

cs-fix:
	docker-compose run --rm php /var/www/vendor/bin/phpcbf --standard=/var/www/phpcs.xml

composer-install:
	docker run --rm --interactive --tty --volume $(PWD):/app --user $(id -u):$(id -g) composer install --ignore-platform-reqs

composer-update:
	docker run --rm --interactive --tty --volume $(PWD):/app --user $(id -u):$(id -g) composer update --ignore-platform-reqs

release:
	make test && make phpstan && make cs && ./vendor/bin/releaser release

Level 4: Code style checking

PHP Code Sniffer

<?xml version="1.0"?>
<ruleset name="Yin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
    <description>PHP Coding Standards for Yin</description>

    <arg name="basepath" value="."/>
    <arg name="cache" value=".phpcs-cache"/>
    <arg name="colors" />
    <arg name="encoding" value="UTF-8"/>
    <arg name="extensions" value="php"/>
    <arg name="parallel" value="80"/>
    <arg name="report" value="code"/>
    <arg name="report-width" value="160"/>

    <!-- Show progress of the run -->
    <arg value="nps"/>

    <file>src/</file>
    <file>tests/</file>

    <rule ref="WoohooLabs"/>
</ruleset>

.phpcs

<?xml version="1.0"?>
<ruleset name="WoohooLabs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../vendor/squizlabs/php_codesniffer/phpcs.xsd">
    <!-- Rules -->
    <rule ref="PSR12"/>

    <!-- Force array element indentation with 4 spaces -->
    <rule ref="Generic.Arrays.ArrayIndent"/>

    <!-- Forbid `array(...)` -->
    <rule ref="Generic.Arrays.DisallowLongArraySyntax"/>

    <!-- Forbid empty statements -->
    <rule ref="Generic.CodeAnalysis.EmptyStatement">
        <!-- But allow empty catch -->
        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
    </rule>

    <!-- Forbid final methods in final classes -->
    <rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>

    <rule ref="Generic.Files.LineLength">
        <properties>
            <property name="lineLimit" value="160"/>
            <property name="absoluteLineLimit" value="200"/>
        </properties>
    </rule>
</ruleset>

Level 5: Static Analysis

PHPStan

  • Require booleans in if, elseif, ternary operator, after !, and on both sides of && and ||.
  • Require numeric operands or arrays in + and numeric operands in -/*///**/%.
  • These functions contain a $strict parameter for better type safety, it must be set to true:
    • ​in_array (3rd parameter)
    • array_search (3rd parameter)
    • array_keys (3rd parameter; only if the 2nd parameter $search_value is provided)
    • base64_decode (2nd parameter)
  • Variables assigned in while loop condition and for loop initial assignment cannot be used after the loop.
  • Disallow empty()
  • Disallow variable variables ($$foo, $this->$method() etc.)
  • Require parameter and return typehints for functions and methods
  • ...

Level 100:

Continuous Integration in place enforcing PHP CS and PHPStan rules

Thanks!

The modern PHP development environment

By Máté Kocsis

The modern PHP development environment

  • 480