PHP Annotated – February 2021

Php_annotated 이미지

Roman Pronskiy가 쓰고 JetBrains에서 제공하는 PHP Annotated 2021년 2월호의 번역/해석본입니다.

이 중에서 몇 가지 제 취향껏 골라 그 안의 내용도 좀 뒤져보고 개발새발 번역해서 소개합니다.


⚡️ News

PHP 8.0.2, 7.4.15, 7.3.27

https://www.php.net/ChangeLog-8.php#8.0.2
https://www.php.net/ChangeLog-7.php#7.4.15
https://www.php.net/ChangeLog-7.php#7.3.27

8.0과 7.4는 SoapClient에 관한 보안 수정 사항을 포함한 다양한 버그 수정이 있었습니다. 7.3 branch에는 보안 수정 사항만 반영되었습니다.

7.2와 이전 버전의 PHP는 더이상 지원받을 수 없습니다. 이전 버전을 사용하고 계시다면 PHP 7.4로 업그레이드 하는 걸 고려해보세요.

PHP-FIG published updates for PSR-6 and PSR-13 standards.

PHP-FIG가 PSR-6PSR-13 표준의 업데이트를 게시했습니다.

PSR 진화 계획(PSR evolution plan)에 정의된 것처럼 두가지의 새로운 버전을 받았습니다.
두 경우 모두 첫 번째 버전은 인수에 유형을 추가하고 두 번째 버전은 이를 반환 값에 추가합니다. 업데이트에는 union type을 사용하거나 return type에 static을 쓰기 때문에 PHP 8 이상이 필요합니다.

PHP-FIG @phpfig의 트윗

두 경우 모두 첫 번째 릴리스는 인수에 유형을 추가하고 두 번째 릴리스는 반환 유형을 추가합니다.
이는 상속과 Liskov의 원칙 제약의 조합으로 인해 최종 사용자가 모든 것을 한 번에 지원하도록 구현하기 불가능하게 합니다.

이 PSR의 사용자라면, 먼저 기존 버전과 함께 신규 두 버전 중 첫번째 버전을 바로 지원할 수 있고, 이후에 새로운 두 버전을 지원하도록 바꿀 수 있습니다. 예를 들어:

psr/link:^1.0 (now, 1.1 already compatible!)
psr/link:^1.1|^2.0 (then)

psr/cache: ^1.0 (now)
psr/cache: ^1.0|^2.0
psr/cache: ^2.0|^3.0

PhpStorm 2021.1 Early Access Program has started

https://blog.jetbrains.com/phpstorm/2021/02/phpstorm-2021-1-eap-2/

다가올 업데이트의 새로운 기능을 먼저 경험해보세요.

  • PHP 설정이 이제 최상위로 올라왔습니다.
  • 새로운 quick-fix: “Invert ‘if’ statement”
    • if문에서 “Invert ‘if’ statement” 옵션을 선택하면 조건문을 반대로 바꾸어 줍니다
  • http:// 링크에 not safe하다는 highlight와 https://로의 quick-fix 제공
  • Split view에서 탭 더블클릭으로 에디터를 최대화
  • bugfix : Debugging WSL2 projects with Docker (WI-53396 +86)

Developer Ecosystem Survey 2021 from JetBrains

https://surveys.jetbrains.com/s3/developer-ecosystem-survey-2021-sh

JetBrains의 2021년 개발자 Ecosystem 설문조사가 진행 중입니다. 조금 길지만 PHP section이 포함되어 있습니다. 몇 가지 PHP 인사이트를 추가로 보려면 작년 결과도 확인해보세요.

part-of-devecosystem-2020-php-image

🐘 PHP Internals

[RFC] Object keys in arrays

https://wiki.php.net/rfc/object_keys_in_arrays

Nikita Popov는 객체를 일반 배열의 키로 사용할 수 있도록 제안합니다.

$obj1 = new stdClass;
$obj2 = new stdClass;

$array = [];
$array[$obj1] = 1;
$array[$obj2] = 2;

var_dump($array[$obj1]); // int(1)
var_dump($array[$obj2]); // int(2)

이렇게 제안하는 이유는 열거형(Enumerations) RFC에서 enum의 값이 객체이기 때문입니다. 따라서 이들을 배열의 키로 사용할 수 없습니다.

그러나 배열을 받아들이는 모든 함수는 정수 또는 문자열 키를 기대하기 때문에 이러한 변경은 중요합니다.

[RFC] Object scoped RNG Implementations

https://wiki.php.net/rfc/object_scope_prng

의사 난수를 생성하기 위한 rand() 및 mt_rand() 함수는 동일한 시드 값 srand()에 대해 동일한 시퀀스를 생성합니다. 그러나 그들은 전역 상태를 사용합니다. 즉, 서로 다른 시드 값을 가진 여러 생성기를 만들어 동시에 사용할 수 없습니다.

Go Kudo는 전역 상태 문제를 해결하기 위해 의사 난수 시퀀스 생성기와 함께 작동하는 객체 API를 추가 할 것을 제안합니다.

$seed = 1234;
$rng = new RNG\MT19937($seed);
$array = [1, 2, 3, 4, 5];

shuffle($array, $rng);

[RFC] Change Default mysqli Error Mode

https://wiki.php.net/rfc/mysqli_default_errmode

mysqli 개선 이니셔티브의 일환으로 이 RFC는 “오류에 대한 예외 발생 모드”를 default로 하는 첫 번째 단계를 제안합니다. 현재 이 결과는 다음과 같이 실행함으로 얻을 수 있습니다:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

mysqli를 사용하는 주요 오픈 소스로는 CodeIgniter, WordPress, phpMyAdmin 등이 있습니다.

Inheritance Cache

https://externals.io/message/113091

Dmitry Stogov는 상속 캐싱을 구현하는 pull request를 제시했습니다.

캐시는 Symfony “Hello World” 애플리케이션의 성능을 8% 향상시킵니다. 그리고 그 결과를 얻기 위해 아무것도 할 필요가 없습니다. PHP 버전을 업데이트하고 opcached가 활성화되어 있는지 확인하십시오.

PHP 클래스는 각각 컴파일되고 (opcache에 의해) 캐시되는데, “연결(linking)”은 매 request마다 run-time에 수행되었습니다.

상속 캐시는 모든 종속 클래스(부모, 인터페이스, trait, property type, 호환성 검사에 관계하는 method type)의 고유한 집합에 대해 한 번 “연결(linking)”을 수행하고 결과를 opcache 공유 메모리에 저장합니다.
이 패치의 일환으로 불변 클래스(unresolved 상수, typed property 및 공변 타입 검사)에 대한 제한을 제거했습니다. 따라서 이제 opcache에 저장된 모든 클래스는 “불변”합니다.
필요하다면 프로세스 메모리에 지연 로드 될 수 있습니다만 일반적으로 한 번만 발생합니다(첫 번째 연결시).

[RFC] Property Accessors (early draft)

https://wiki.php.net/rfc/property_accessors

Nikita는 각 속성에 대해 별도의 getter/setter 접근자를 제공하는 제안 초안을 만들었습니다.

이 RFC는 몇 가지 기능을 추가 할 것을 제안합니다.

비대칭적인 액세스 수정자를 선언하는 기능:

class User {
public string $name { get; private set; }
// или вот так (또는 이렇게)
public string $prop { public get; private set; }
}

read-only properties 선언:

class Test {
// Read-write property.
public $prop { get; set; } // the same as `public $prop;`

// Read-only property.
public $prop { get; }
}

guard라는 키워드로 유효성 검사를 추가하는 기능:

class User {
public string $name {
guard {
if (strlen($value) === 0) {
throw new ValueError("Name must be non-empty");
}
}
}
}

2013년에 PHP 5.5에 대해 비슷한 제안이 논의되었지만, 투표에서 실패했습니다.

현재로서는 아직 내부에서 논의되지 않은 아주 초반의 draft이므로 공식 발표를 기다려보면 좋겠습니다.

🗳 [RFC] var_representation() : readable alternative to var_export()

https://wiki.php.net/rfc/readable_var_representation

var_export() 함수는 오랫동안 불만의 대상이었습니다. 적어도 배열 구문을 array()에서 []로 변경하라는 제안이 있는 RFC 있었습니다.

이제 var_export()의 결함을 수정하는 새로운 함수를 간단히 소개하는 제안이 올라왔습니다.

var_representation($value, int $flags=0) :string

이 글을 뒤늦게 번역하는 2월 27일 시점에는 이미 투표가 끝났고, 최종 결과는 9:10으로 거절(Declined) 상태가 됐습니다.

🗳 [RFC] Enumerations

  • 사실은 ✅ [RFC] Enumerations

https://wiki.php.net/rfc/enumerations#voting

열거형(Enumerations)에 대한 투표가 진행되고 있고, 매우 유망하다는 소식을 번역하는 시점이 너무 늦다보니… 이미 투표에서 44:7로 통과 되었고, 8.1 버전에 반영될 예정입니다.

✅ [RFC] Array unpacking with string keys

https://wiki.php.net/rfc/array_unpacking_string_keys

문자열 키를 가진 배열을 분해하는 방식에 관한 제안이 통과되었습니다. 8.1 버전에 반영될 예정입니다.

❌ [RFC] Dump results of expressions in php -a

https://wiki.php.net/rfc/readline_interactive_shell_result_function

거절(Declined) 됐습니다.

New in PHP 8.1

https://stitcher.io/blog/new-in-php-81

Brent Roose의 변경 사항이 생기면 업데이트 되는, PHP 8.1의 새로운 기능에 대한 개요입니다. 더 자세한 정보를 원하시면 php.watch에서 변경 사항 목록을 확인하십시오.

PHP RFC Watch에서 새로운 RFC 및 투표를 팔로우 할 수도 있습니다.

🛠 Tools

fabpot/local-php-security-checker

https://github.com/fabpot/local-php-security-checker

알려진 취약성이 있는 의존성이 있는지 composer.json을 확인합니다. FriendsOfPHP/security-advisories가 취약성 데이터베이스로 사용됩니다.

funivan/PhpClean

https://github.com/funivan/PhpClean

모든 곳에 유형을 선언하고, 불필요한 주석이 없고, 상속 대신 합성(composition)을 사용하는 등 흥미로운 inspection을 많이 추가한 PhpStorm 용 플러그인. 이 소개글로부터 더 자세히 알아보세요.

wasmerio/wasmer-php

https://github.com/wasmerio/wasmer-php

PHP 용 WebAssembly 런타임. 확장을 사용하면 PHP에서 wasm 바이너리를 실행하고 사용할 수 있습니다. 예를 들어 Rust 라이브러리를 가져와 Wasm으로 컴파일하고 Composer 패키지처럼 PHP의 모든 플랫폼에서 사용할 수 있습니다. 성능도 꽤 좋습니다. 이 블로그 게시글에서 이에 대해 자세히 알아볼 수 있습니다.

temporalio/sdk-php

https://github.com/temporalio/sdk-php

진행중인 작업임에도 불구하고, Uber에서 사용하는 이벤트 소싱 엔진인 temporal.io를 위한 매우 흥미로운 PHP-SDK입니다.

다음은 누적(cumulative) 트랜잭션의 예입니다.

#[Workflow\WorkflowInterface]
class LoopWorkflow
{
private array $values = [];
private array $result = [];
private $simple;

public function __construct()
{
$this->simple = Workflow::newActivityStub(
SimpleActivity::class,
ActivityOptions::new()->withStartToCloseTimeout(5)
);
}

#[SignalMethod]
public function addValue(
string $value
) {
$this->values[] = $value;
}

#[WorkflowMethod(name: 'LoopWorkflow')]
public function run(
int $count
) {
while (true) {
yield Workflow::await(fn() => $this->values !== []);
$value = array_shift($this->values);

$this->result[] = yield $this->simple->echo($value);

if (count($this->result) === $count) {
break;
}
}

return $this->result;
}
}

여기선 RoadRunnerreactphp/promise를 사용합니다.

vimeo/php-mysql-engine

https://github.com/vimeo/php-mysql-engine

순수 PHP로 구현한 MySQL 쿼리 시뮬레이터 (엔진). 이 도구에 대한 게시글에서 Matt Brown은 이 엔진을 구현하여 Vimeo에서 테스트를 두 배 빠르게 실행하는 방법에 대해 이야기합니다.

cweagans/composer-patches

https://github.com/cweagans/composer-patches

의존하는 대상에 패치를 적용할 수 있는 Composer 용 플러그인입니다. 이는 변경 사항이 너무 구체적이고 패키지/프레임워크에 대한 완전한 PR을 보내긴 적절하진 않고, 포크를 유지하고 싶지도 않은 경우에 유용합니다.

Symfony

chaos-php/chaos-monkey-symfony-bundle

https://github.com/chaos-php/chaos-monkey-symfony-bundle

Symfony 앱 용 Chaos Monkey 같은 라이브러리. 응용 프로그램의 안정성을 테스트하기 위해 모든 종류의 극한 상황을 재현합니다.

A week of Symfony #736 (February 1-7 2021)

https://symfony.com/blog/a-week-of-symfony-736-1-7-february-2021

Elasticsearch – the right way in Symfony.

https://jolicode.com/blog/elasticsearch-the-right-way-in-symfony

Symfony에서 Elasticsearch를 제대로 쓰기

Laravel

Laravel adds parallel testing capabilities

https://blog.laravel.com/laravel-parallel-testing-is-now-available

Laravel v8.25부터 paratestphp/paratest 기반의 병렬 테스트 기능을 추가합니다. 병렬로 실행되도록 테스트를 조정하는 방법에 대한 이 블로그 게시물을 읽어보세요.

Laravel: New Release Schedule

https://blog.laravel.com/updates-to-laravels-versioning-policy

이제 메이저 버전이 6개월 마다가 아니라 1년에 한 번 릴리스 됩니다. 일정은 laravelversions.com에서 확인할 수 있습니다.

📺 Building a multi-domain multi-tenant SaaS app with JetStream

https://www.youtube.com/watch?v=5CjWPU7lns4

by Julien Bourdeau.

📺 Laravel Worldwide Meetup #5

Yii

New components of the upcoming Yii 3

기타 읽을 만한 글

Getting started with mutation testing

https://johnbraun.blog/posts/mutation-testing

Maks RafalkoInfection PHP를 사용하여 Mutation Test를 하는 방법을 설명합니다.

Mutation Testing은 기존 테스트 스위트에 대해 실행되는 소스 코드에서 돌연변이를 생성합니다. 이러한 테스트 중 어느 것도 실패하지 않으면 이 소스 코드(변이)가 약하게 테스트되었다는 신호입니다.

Colliding PHP arrays

https://sorin.live/colliding-php-arrays/

PHP의 배열이 DoS 공격을 수행하는 해시 테이블이라는 사실을 이용하는 방법에 대한 흥미로운 게시물입니다.

PHP의 배열은 사실 내부적으로는 해시 맵으로 구현되어 있고, 그 구현 방식이 해싱 충돌에 의한 서비스 거부(collision denial of service) 공격에 취약하다는 사실은 오래된 뉴스이고 많은 프로그래밍 언어에서 공통적으로 발견됩니다.
이 글은 이 원리를 설명하며 $_POST, $_GET and $_COOKIE를 통한 공격과 이를 방지하기 위한 max_input_vars 설정까지 설명합니다.

2011년에 Nikita가 쓴 PHP 배열에 2 ^ 16 = 65536 값을 삽입하는 데 예상되는 0.01 초 대신 30 초가 걸리는 방법에 대한 유사한 게시물을 기초로 작성했습니다.

php.watch: PHP Curl Security Hardening

https://php.watch/articles/php-curl-security-hardening

이 글 PHP에서 cURL을 사용할 때 안전하지 않을 수 있는 장소를 식별하고 자신을 보호하는 방법에 대해 설명합니다.

Summary

  • Limit Curl Protocols
  • Do not enable automatic redirects unless absolutely necessary
  • If redirects are enabled enabled, limit allowed protocols (if different from #1 above)
  • If redirects are enabled, set a strict limit
  • Set a strict time-out
  • Do not disable certification validation, or enforce it
  • Disable insecure SSL and TLS versions

Build a Telegram bot in PHP

https://pretzelhands.com/posts/build-a-telegram-bot-in-php

PHP로 Telegram 봇을 빌드하고 beyondcode/expose를 사용하여 로컬에서 테스트합니다.

How to build a dynamic GitHub profile

https://hackernoon.com/how-to-build-a-dynamic-github-profile-with-github-actions-and-php-h5g34cr

GitHub Actions와 PHP로 동적으로 GitHub profile을 만드는 법.

Webshell was hidden in an infected PHP script in whitespace characters

https://blog.sucuri.net/2021/02/whitespace-steganography-conceals-web-shell-in-php-malware.html

Webshell은 감염된 PHP 스크립트에 공백 문자로 숨겨져 있습니다. 감염된 서버에서 발견된 백도어 분석.

Contract Tests

https://www.kai-sassnowski.com/post/contract-tests/

인터페이스의 모든 구현에서 일관된 동작을 보장하기 위해 테스트를 작성하는 방법.

Benchmarks of different frameworks and CMSs with PHP 5.6, 7.*, and 8.0

https://kinsta.com/blog/php-benchmarks/

PHP 5.6, 7.* 및 8.0을 사용하는 다양한 프레임워크 및 CMS의 벤치마크.

📺 Videos

8 Things You’ll ❤️ About PHP 8

https://www.youtube.com/watch?v=ZZxCj91NjWg

by Gary Clarke.

Xdebug 3: Diagnostics

https://www.youtube.com/watch?v=IN6ihpJSFDw

Xdebug가 동작하지 않을 때 해야할 것

Refactoring PHP Platform – LiveStream #3

https://www.youtube.com/watch?v=trVMpLtDqzA

from Christoph Rumpel.

How to use the terminal in PhpStorm by Christoph Rumpel.

https://www.youtube.com/watch?v=h1sGfV5i_kI

PhpStorm에서 터미널 사용하기.
Christoph가 진행할 다른 강의도 확인해보세요: Mastering PhpStorm.

Live-coding a Bref Queue

https://www.youtube.com/watch?v=tVsnbvCd6Wg

Bref의 저자인 Matthieu Napoli가 AWS Lambda에서 PHP로 SQS와 EventBridge를 활용한 “Bref Messaging” 라이브러리를 소개합니다.

Creating generative art with PHP

https://www.youtube.com/watch?v=-qi4OCC7oOM

PHP로 예술 작품을 만들면서 Blackfire.io로 프로파일링하기.

PHP Release Radar:

  • Episode 2: PHP 8 – Sara Golemon과 Gabriel Caruso가 8.0, PHP 확장의 기본 사항 및 프로젝트에 참여하는 다양한 방법에 대해 논의합니다.
  • Episode 3: Psalm 4 – Psalm의 저자인 Matt Brown와 함께.
  • Episode 4: XDebug 3 – Derick Rethans과 함께.

🔈 Podcasts

PHP Ugly podcast:

  • #222: – PHP Security Tools.
  • #221: – The PHP Big Short.

PHP Internals News podcast: