PHP Annotated – January 2021

Php_annotated 이미지

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

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


⚡️ News

PHP 8.0.1, 7.4.14, 7.3.26

https://www.php.net/ChangeLog-8.php#8.0.1
https://www.php.net/ChangeLog-7.php#7.4.14
https://www.php.net/ChangeLog-7.php#7.3.26

url_parse()에 있던 취약점 CVE-2020-7071를 수정한 버전입니다. 8.0과 7.4는 또한 많은 수정 사항이 있지만, 7.3은 이제 보안 관련 수정 만 제공됩니다(security-fixes-only).

github.com/php/doc-base

https://github.com/php/doc-base

모든 PHP 문서가 Git으로 옮겨왔습니다 : github.com/php/doc-base

PhpStorm 2020.3

https://blog.jetbrains.com/phpstorm/2020/12/phpstorm-2020-3-release/

여러분이 놓쳤을까봐 이야기 하는데, PHP 8, PHPStan, Psalm, Xdebug 3, Tailwind CSS, 그리고 pair programming을 지원하는 새로운 PhpStorm이 출시 됐습니다.

저(번역자)는 재택 근무 시 팀원들과 같이 코드볼 때 가끔 사용하는데 (화면 공유에 비해서) 정말 편합니다.

PHP Versions Stats – 2020.2

https://blog.packagist.com/php-versions-stats-2020-2-edition/

Packagist.org에 연결할 때 Composer가 보내는 데이터를 기반으로 한 전통적인 통계 모음.

  • PHP 7.4: 42.61% (+22.55)
  • PHP 7.3: 27.05% (-3.00)
  • PHP 7.2: 15.28% (-12.21)
  • PHP 7.1: 7.45% (-4.1)
  • PHP 5.6: 2.71% (-2.28)
  • PHP 7.0: 2.70% (-1.30)

The Online PHP Conference 2021

https://thephp.cc/dates/2021/01/the-online-php-conference

1월 18일 ~ 22일 - 라인업을 확인해보세요. 아직 티켓을 살 수 있습니다!

🐘 PHP Internals

✅ [RFC] Restrict $GLOBALS usage

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

$GLOBALS를 제한하는 RFC가 만장일치로 통과했습니다. 8.1부터 적용되며 읽고, 쓰고, isset/unset을 호출하는 것은 가능합니다.

$GLOBALS['x'] = 1;

echo $GLOBALS['x'];

isset($GLOBALS['x']);
unset($GLOBALS['x']);

하지만 $GLOBALS 자체를 변경하는 건 에러를 발생시킵니다.

$GLOBALS = [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);

$GLOBALS를 function by reference로 전달해도 에러가 발생합니다.

asort($GLOBALS);
// > Compile-time error

The implementation of this RFC simplifies the internals of PHP and improves the performance of array operations.
이 RFC의 구현으로 PHP 내부를 단순화하고 배열 조작/작업 성능을 높일 수 있습니다.

RFC의 소개글:

$GLOBALS 변수는 현재 PHP의 내부 기호 테이블에 대한 직접 참조를 제공합니다. 이를 지원하려면 상당한 기술적 복잡성이 필요하고 PHP의 모든 어레이 작업 성능에 영향을 주지만 거의 사용되지 않습니다. 이 RFC는 $GLOBALS의 지원되는 사용을 제한하여 대부분의 코드가 그대로 작동하도록 허용하면서 문제가 있는 경우를 허용하지 않습니다.

[RFC] Enumerations

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

Ilija Tovilo와 Larry Garfield는 다른 언어에서 enum이 어떻게 구현되었는지 연구했고, Swift, Rust, Kotlin의 영감을 얻어 RFC를 제안했습니다.

Enum은 본질적으로 키워드 enum 및 case로 선언 된 Type입니다.

enum Suit {
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}

값 중 하나를 변수에 할당하거나 인수로 전달할 수 있습니다.

$val = Suit::Diamonds;

function pick_a_card(Suit $suit) { ... }

pick_a_card($val); // OK
pick_a_card(Suit::Clubs); // OK
pick_a_card('Spades'); // TypeError

Enum은 singleton 객체처럼 동작합니다.

$a = Suit::Spades;
$b = Suit::Spades;

$a === $b; // true

$a instanceof Suit; // true

Scalar Enum을 선언할 수도 있습니다. Scalar 값이 예상되는 컨텍스트에서 투명하게 사용할 수 있습니다.

enum Suit: string {
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}<br/>
echo "I hope I draw a " . Suit::Spades;
// prints "I hope I draw a S".

$a instanceof Suit::Spades; // true
Enum은 method(static 포함), property, 상수를 포함할 수 있습니다.

enum UserStatus: string {
case Pending = 'pending';
case Active = 'active';
case Suspended = 'suspended';
case CanceledByUser = 'canceled';
public function label(): string {
return match($this) {
UserStatus::Pending => 'Pending',
UserStatus::Active => 'Active',
UserStatus::Suspended => 'Suspended',
UserStatus::CanceledByUser => 'Canceled by user',
};
}
}
foreach (UserStatus::cases() as $key => $val) {
printf('<option value="%s">%s</option>\n', $key, $val->label());
}
  • Enum이나 UnitEnum interface 구현체는 cases()라는 static method를 포함하는데, 선언된 순서에 따른 Case의 목록을 리턴합니다.

특정 case에 Enum method를 포함할 수 있지만, 각 case는 그들만의 method나 상수를 가질 수 없습니다. name이나 value와 같은 특별한 property를 갖고 있지만, 각 case는 단순히 값일 뿐입니다.

Enum은 serialize될 수도 있습니다.

Suit::Hearts === unserialize(serialize(Suit::Hearts));

여기까지 주요 특징만 살펴봤는데, 전체 RFC를 더 읽어보세요.

[RFC] Fibers

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

비동기 PHP에 대한 거대한 RFC가 올라왔습니다. 기본적으로 fiber는 자체 stack이 있는 함수이므로 언제든지 중지하고 다시 시작할 수 있습니다. 이는 우리가 ReactPHP / Amp와 같은 라이브러리 기반의 비동기 코드를 훨씬 단순하고 직관적으로 작성하게 해줍니다.

reddit에 올라온 글에서 trowski2002의 댓글:

Fiber API를 사용하면 Go와 유사한 API를 사용자 공간에 작성할 수 있습니다. 이 스타일에 접근하는 데는 몇 가지 다른 방법이 있습니다. 이것이 RFC가 이를 가능하게 하는 최소한의 요구사항만 코어에 제공하고, 의견이 분분한 부분은 사용자 공간에 남기는 이유입니다.

ReactPHP를 개발하는 Cees-Jan Kiewiet(@WyriHaximus)의 트윗

우린 이 긴 목록에 관심이 정말 많고, ext-fibers를 이번 휴가 때 확인해보려고 합니다. @_trowski가 만든 훌륭한 react-fiber도 함께.

이에 대한 Aaron Piotrowski(@_trowski)의 답변

ReactPHP는 ext-fiber에 의해 절대적으로 쓸모가 없어졌습니다. Fiber는 기존의 동기 코드에 더 쉽게 통합 할 수 있기 때문에 사람들에게 ReactPHP를 사용하는 이유보다 많은 것을 제공할 것입니다. 나는 모호함 없이 비동기 PHP가 보편화되기를 고대하고 있습니다.

Amp v3는 여전히 개발 중입니다. 하지만 이미 promise 대신 fiber를 사용하고 있습니다. 다음은 async/await 구문이 어떻게 보이는지에 대한 예입니다.

use Amp\Delayed;
use Amp\Loop;
use function Amp\async;
use function Amp\await;

//클로저는 Promise 또는 Generator가 아닌 반환 유형으로 int를 선언하지만 코 루틴처럼 실행됩니다.
$callback = function (int $id): int {
return await(new Delayed(1000, $id)); // Await promise resolution.
};

// $callback을 호출하면 int가 반환되지만 비동기 적으로 실행됩니다.
$result = $callback(1); // 이 green thread 내에서 서브 루틴을 호출하여 리턴하는 데 1 초가 걸립니다.
\var_dump($result);

// 두 개의 새로운 green thread를 동시에 실행하고 이 green thread에서 해결을 기다립니다.
$result = await([ // 동시에 실행하면 대기하는 동안 1 초만 경과합니다.
async($callback, 2),
async($callback, 3),
]);
\var_dump($result); // 전체 스크립트가 시작된 후 2 초 내에 실행됩니다.

[RFC] #[Deprecated] Attribute

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

PHP 8은 attribute에 대해 내부 hooking을 위한 지원을 추가했지만, 실제 사용할 수 있는 속성은 없었습니다. 공식적으로 제안 된 첫 번째 Attribute는 쓸모없는 메소드와 기능을 표시하기 위한 #[Deprecated]입니다. #[Deprecated]가 표시된 함수나 메소드를 호출하면 PHP는 E_DEPRECATED 에러를 throw합니다.
유사하지만 약간 더 고급 속성이 이미 PhpStorm 2020.3에 있습니다. 그러나 native 속성이 이미 final로 선언되었기 때문에, 이와 호환하기 위한 좋은 방법을 찾지 못해 PhpStorm에서 이 기능을 제거할 것을 고려하고 있습니다.

[RFC] #[NamedParameterAlias] Attribute

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

PHP 8.1을 위한 또 하나의 attribute 아이디어입니다.

명명된 인수(named arguments)에 대해 토론하고 투표하는 동안 매우 논쟁의 여지가 있는 점이 하나 있었습니다. 바로 이름 바꾸기의 하위 호환성 문제였습니다. OSS 관리자는 매개 변수 이름이 이제 API의 일부가 되며 쉽게 변경할 수 없다고 지적했습니다.

이 주제에 대한 별도의 RFC도있었습니다: Named Parameters explicit opt-in

이제 좀 더 간단한 솔루션이 있습니다. 매개 변수에 속성을 추가하여 별칭, 즉 매개 변수의 대체 이름을 지정합니다.

<?php
use NamedParameterAlias;

// Old function signature:
function log($arg1) {}

// New function signature introduces better name
function log(#[NamedParameterAlias("arg1")] $message) {}

log(arg1: "Hello World!");
log(message: "Hello World!");

[PR] Add support for property initialization during cloning

https://github.com/php/php-src/pull/6538

이 pull request는 변경 불가능한 객체 복제를 위한 구문 개선을 제공합니다.

현재:

{
$self = clone $this;
$self->bar = $bar;
$self->baz = $baz;<br/>

return $self;
}

제안:

{
return clone $this with {
bar: $bar,
baz: $baz,
};
}

[RFC] Add array_is_list(array $array): bool

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

연속적인 정수 키가 있는 배열을 전달하면 참을 반환하는 함수를 추가 할지 투표가 시작되었습니다(2021-01-06 ~ 2021-01-20).

[RFC] Short match

https://wiki.php.net/rfc/short-match

match 구문을 더 짧게!

[RFC] Concepts to improve mysqli extension

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

mysqli extension 개선을 위한 제안.

[RFC] Array unpacking with string keys

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

spread_operator_for_array에서 문자열 키를 배열로 풀 수 있도록 제안.

[PR] Use ‘ENT_QUOTES|ENT_SUBSTITUTE’ for HTML encoding and decoding functions

https://github.com/php/php-src/pull/6583

HTML encoding/decoding 함수에 ENT_QUOTES|ENT_SUBSTITUTE 옵션을 사용하도록 변경하자는 제안

PHP 8.1 received super fast hashing algorithms: xxHash and MurmurHash3.

PHP 8.1에서 엄청 빠른 해싱 알고리즘인 xxHashMurmurHash3를 받아들였습니다.

🛠 Tools

💵 Dump Debugging Evolved – Ray

https://freek.dev/1868-introducing-ray-a-debugging-tool-for-pragmatic-developers

Spatie에서 Ray라는 디버깅 앱을 발표했습니다. PHP 스크립트를 실행하는 중에 ray($anything)와 같이 호출하면, 별도의 데스크탑 어플리케이션에서 멋지게 표시됩니다. Xdebug보다 dump-and-die 방식을 선호하는 경우 시도해보십시오.

자세한 건 📺 video overview에서 확인해보세요.

vimeo/php-mysql-engine

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

순수 PHP로 만들어진 이 MySQL 엔진은 테스트 할 때 데이터베이스에 액세스하고 메모리에서 MySQL을 에뮬레이션하여 테스트 시작 속도를 높이고자 할 때 유용할 수 있습니다. 이 라이브러리는 PDO를 상속하여 일반적인 PDO의 MySQL 메소드를 사용할 수 있게 해줍니다. 그러나 몇가지 제약이 있기도 합니다.

mbunge/php-attributes

https://github.com/mbunge/php-attributes

PHP 8 Attribute를 쉽게 사용하고 적용할 수 있게 도와주는 패키지입니다.

  • 클래스 및 클래스 구성 요소에 PHP 8 attribute 적용
  • autoloaded 된 클래스에 자동으로 속성 적용
  • 클래스 이름, 네임 스페이스 또는 클래스 리플렉션의 조건을 필터링하도록 속성 제한

mlocati/docker-php-extension-installer

https://github.com/mlocati/docker-php-extension-installer

이 도구를 사용하면 Docker에 PHP 확장을 쉽게 설치할 수 있습니다. PECL은 더 이상 사용할 수 없으므로 PHP 8에 유용합니다.

php-opencv/php-opencv

https://github.com/php-opencv/php-opencv

PHP 8을 지원하는 컴퓨터 비전(얼굴 및 물체 인식 등) 및 기계 학습을 위한 확장입니다. 예제를 참조하세요.

pestphp/pest v1.0

https://github.com/pestphp/pest

보다 간단한 방식으로 테스트를 작성할 수있는 테스트 도구 Pest의 첫 번째 stable 릴리스입니다.

Rector 0.9

https://getrector.org/blog/2020/12/28/rector-09-released

자동 리팩토링 및 코드 업데이트를 위한 도구입니다.

FriendsOfPHP/proxy-manager-lts

https://github.com/FriendsOfPHP/proxy-manager-lts

이전 버전과의 호환성이 확장된, 인기있는 Ocramius/ProxyManager 패키지의 포크입니다.

multiavatar/multiavatar-php

https://github.com/multiavatar/multiavatar-php

이 스크립트는 사용자 이름(어떤 문자열이든)을 기반으로 재미있는 아바타를 생성합니다. 다음은‘PhpStorm’입니다.

Multiavatar-PhpStorm 이미지

Symfony

5 New Combos opened by Symfony 5.2 and PHP 8.0

https://tomasvotruba.com/blog/2020/12/21/5-new-combos-opened-by-symfony-52-and-php-80/

How to create service bundles for a Symfony application

https://macrini.medium.com/how-to-create-service-bundles-for-a-symfony-application-f266ecf01fca

A week of Symfony #732 (January 4–10, 2021)

https://symfony.com/blog/a-week-of-symfony-732-4-10-january-2021

Symfony 2020 in review

https://symfony.com/blog/symfony-2020-year-in-review

📺 Consume a 3rd-party API with Test Driven Development + HttpClient

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

Laravel

🔈 Taylor Otwell’s Laravel Snippet #26 podcast

https://blog.laravel.com/laravel-snippet-26

Jetstream 2.x, Forge Circles, Spark “Next”, React SPAs.

Configuration precedence when testing Laravel

https://jasonmccreary.me/articles/laravel-testing-configuration-precedence/

테스트를 실행할 때 앱 Configuration의 우선 순위를 알려줍니다.

📺 A stream from Freek Murzee, where he refactors one of his applications – Mailcoach.

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

📺 Laravel Internals #3

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

전체 Laravel 팀과 함께하는 유튭 스트림.

Yii

Yii news 2020, issue 8

https://opencollective.com/yiisoft/updates/yii-news-2020-issue-8

📺 E-commerce website on Yii 2

https://www.youtube.com/watch?v=eQdDBhQpU9o&list=PLLQuc_7jk__UvpbpU3no5zveJQAwID48B

12시간 동안 Yii2로 Yii2 E-commerce application를 만드는 비디오.

Laminas

Laminas Project: A Year in Review.

https://www.zend.com/blog/laminas-2020

Vulnerability reported in Zend Framework / Laminas

https://www.bleepingcomputer.com/news/security/zend-framework-disputes-rce-vulnerability-issues-patch/

Zend Framework / Laminas에서 발견된 취약성을 요약하자면 다음과 같습니다.

class MyClassWithToString {
public $name;

public function __construct($name) {
$this->name = $name;
}

public function __toString() {
return (string) $this->name;
}
}

$input = unserialize('O:19:"MyClassWithToString":1:{s:4:"name";s:15:"/tmp/etc/passwd";}');
if ($input instanceof MyClassWithToString) {
unlink($input);
}

팀은 프레임 워크에 수정 사항을 적용했습니다. 하지만 자세히 살펴보면 취약점은 사용자의 데이터 역 직렬화와 관련이 있습니다. 그리고 그런 경우에는 unserializie ()를 사용하지 말아야한다고 php.net에 빨간색으로 표시되어 있습니다.

더욱이 2017년 이후 deserialization 버그는 더 이상 보안 문제로 간주되지 않습니다. 단순히 unserialize()가 안전하지 않기 때문입니다.

Nikita Popov(@nikita_ppv)의 트윗

PSA: Don’t use unserialize() on untrusted input (see http://php.net/unserialize)
PHP will no longer treat unserialize() bugs are security bugs.

다음은 Yii를 예로 사용하여 이러한 버그를 악용하는 또 다른 글입니다.

기타 읽을 만한 글

Scaling PHP FPM based on utilization demand on Kubernetes

https://blog.wyrihaximus.net/2021/01/scaling-php-fpm-based-on-utilization-demand-on-kubernetes/

Object properties and immutability

https://peakd.com/hive-168588/@crell/object-properties-and-immutability

PHP에서 쓰기 제한을 구현하는 방법에 대한 Larry Garfield의 자세한 분석. 결론적으로 그는 읽기 및 쓰기 액세스를 위한 별도의 수정자를 추가 할 것을 제안합니다. 예를 들어, get, set 및 복제 기능을 위한 별도의 public/private 메소드.

시리즈의 두 번째 게시물에서 Larry는 PSR-7을 예로 들어 첫 번째 게시물의 모든 아이디어를 검토합니다.

mastering binary and bitwise data in PHP

https://thephp.website/en/issue/bitwise-php/

PHP에서 바이너리와 비트 데이터 마스터를 위한 기본적인 게시글.

Profiling PHP in production at scale

https://calendar.perfplanet.com/2020/profiling-php-in-production-at-scale/

Wikipedia의 수석 엔지니어 인 Timo Tijhof의 게시물입니다. 두 가지 도구를 사용하는 방법에 대해 설명합니다.

60 초의 샘플 간격을 사용하여 특정 데이터 센터에있는 150 개의 Apache 서버 클러스터에서 매일 약 3 백만 개의 샘플을 수집합니다. 이들은 모두 단일 Redis 인스턴스에서 수신됩니다.

It’s not legacy code — it’s PHP

https://medium.com/vimeo-engineering-blog/its-not-legacy-code-it-s-php-1f0ee0462580

Psalm의 저자 인 Matt Brown이 Vimeo에서 PHP를 사용하는 방법과 이유에 대한 영감을 주는 게시물입니다.

한동안 임박한 느낌이 들었지만 우리는 PHP를 포기하지 않았습니다. 몇 가지 분명한 이유가 있습니다. 전체 코드베이스를 다시 작성하는 것은 리소스 집약적이고 오류가 발생하기 쉽습니다. 그러나 약간 덜 분명한 이유도 있습니다. PHP가 더 좋아졌습니다.

Psalm의 핵심 기능은 TypeScript의 검사기와 대체로 유사하며 Hack이라는 Facebook (PHP 파생) 언어에서 몇 가지 아이디어를 차용합니다. Psalm은 PHP 코드가 프로덕션에서 유형 오류를 일으킬 수있는 경우와 논리가 의미가없는 경우를 알려줍니다. 사용하지 않는 클래스 및 메서드 감지와 같은 몇 가지 추가 기능을 추가하고 Psalm은 자동으로 찾은 많은 문제를 수정할 수 있습니다.

📺 Videos

📺 A pragmatic introduction to Event Sourcing

EventSaucePHP/EventSauce의 저자인 Frank de Jonge의 비디오.

📺 A video code-review from Matthieu Napoli

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

이 에피소드에서 m50/simple를 살펴봅니다.

📺 Xdebug 3 modes

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

Xdebug의 저자인 Derick Rethans가 debugger/profiler/coverage collector로써 Xdebug를 설정하는 방법을 알려줍니다.

🙌 Community

PHP-FIG now has a Discord server

https://www.php-fig.org/blog/2020/12/announcing-new-discord-server/

A 3D model of elePHPant.

https://cults3d.com/en/3d-model/various/elephpant-3d

github.com/thank-you-php

https://github.com/thank-you-php/thank-you-php

PHP에 대한 공개 감사의 편지. 풀 요청을 보내서 가입하고 프로필에 아래와 같은 배지를 받을 수 있습니다.
thank-you-php 배지 이미지

elephpant PHP8 : InPHPinity is born

https://inphpinity.elephpant.com/

새로운 PHP 8 코끼리를 선주문 할 수 있습니다.