PHP 개발. Symfony 콘솔 컴포넌트 - 팁과 요령
이 문서는 심포니 콘솔 개발에 대한 가장 유용하고 검색하기 쉬운 팁과 요령을 보여드리기 위해 작성되었습니다.
PHP의 새 버전이 곧 출시됩니다. 새롭게 구현된 기능에는 어떤 것들이 있나요? 이 글을 통해 알아보세요!
PHP 8.2 가 곧 출시될 예정입니다. 아마도 PHP 8로 업그레이드하는 것이 모두에게 매력적으로 느껴지는 버전이 될 것입니다. 개발자가 기대할 수 있는 기능에 대해 이야기해 보겠습니다. PHP 8.2 최신 버전에 대비하세요. 하지만 먼저 PHP의 모든 버전과 수년간의 변경 사항을 빠르게 살펴봅시다.
<?php
User 클래스 {
public int $id;
public string $name;
}
?>
<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
<?php
클래스 A {}
클래스 B는 A {}를 확장합니다.
Producer 클래스 {
공용 함수 메서드(): A {}
}
ChildProducer 클래스 확장 프로듀서 {
public function method(): B {}
}
?>
<?php
$array['key'] ??= computeDefault();
//는 대략 다음과 같습니다.
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['사과', '배'];
$fruits = ['바나나', '오렌지', ...$parts, '수박'];
// ['바나나', '오렌지', '사과', '배', '수박'];
?>
<?php
// 객체의 필요한 모든 상태가 포함된 배열을 반환합니다.
public function __serialize(): array;
// 주어진 데이터 배열에서 객체 상태를 복원합니다.
public function __unserialize(array $data): void;
?>
2020년 11월에 출시된 PHP 8.0은 다음과 같은 역대 최고의 기능을 제공합니다:
htmlspecialchars($string, double_encode: false);
포스트 컨트롤러 클래스
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
클래스 Point {
공용 함수 __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
Number 클래스 {
공용 함수 __construct(
private int|플로트 $number
) {}
}
new Number('NaN'); // TypeError
에코 매치 (8.0) {
'8.0' => "오, 안돼!",
8.0 => "이게 내가 예상했던 거야",
};
//> 내가 예상한 대로입니다.
$국가 = $세션?->사용자?->겟어드레스()?->국가;
열거형 상태
{
case Draft;
case Published;
case 보관됨;
}
함수 acceptStatus(Status $status) {...}
블로그 데이터 클래스
{
공용 읽기 전용 상태 $status;
공용 함수 __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
서비스 클래스
{
private Logger $logger;
공개 함수 __construct(
로거 $logger = 새로운 NullLogger(),
) {
$this->logger = $logger;
}
}
함수 count_and_iterate(Iterator&Countable $value) {
foreach ($value as $val) { {
echo $val;
}
count($value);
}
$response = $httpClient->request('https://example.com/');
print json_decode($response->getBody()->buffer())['code'];
PHP 8.2 는 개발자의 삶을 더 편리하게 만들고 작업을 더욱 최적화하기 위한 추가 변경 사항을 소개합니다. 아래는 새로운 기능 목록입니다.
새 버전의 PHP에서 가장 크게 개선된 기능 중 하나는 바로 읽기 전용
클래스를 추가합니다. 이 기능으로 설명된 클래스는 해당 변수에 대해 자동으로 전파됩니다. 이제 DTO 클래스가 깔끔하게 보입니다!
읽기 전용 클래스 InvoiceDTO
{
공용 함수 __construct(
public UUID $uuid,
public Issuer $issuer,
public DateTime $issuedAt,
) {}
}
두 번째로 큰 변화는 클래스에서 동적 변수가 더 이상 사용되지 않는다는 것입니다. 다음 구현에서는 더 이상 사용되지 않습니다. PHP 8.2 그리고 오류 예외
PHP의 향후 버전에 포함될 예정입니다.
MyUser 클래스
{
공용 문자열 $name;
}
(...)
$myUser->name = 'Name'; // OK
$myUser->surname = 'Surname'; // 폐기 / 에러 예외
한 가지 언급할 만한 점은 __get
그리고 __set
메서드 및 클래스에서 직접 상속하는 stdClass
는 여전히 아무런 장애물 없이 마법 방법을 구현할 수 있습니다.
또한 여기에서는 깃허브의 흥미로운 스레드에서 PHP-CS 개발자들이 이 변경 사항과 새 버전의 언어에 맞게 인기 있는 도구를 수정할 필요성에 대해 논의합니다.
마지막으로, 어노테이션을 통해 이 동작을 비활성화할 수 있습니다.
#[허용동적프로퍼티]
MyUser 클래스
{
public string $name;
}
$myUser->surname = 'Surname'; // OK
null
, true
및 false
지금까지는 항상 true
또는 false
값으로 설명해야 했습니다. bool
유형입니다.
function alwaysTrue(): bool { return true; }
이제부터 다음을 사용할 수 있습니다. true
그리고 false
를 함수의 반환 값에 단순 유형으로 사용할 수 있습니다.
function alwaysTrue(): true { return true; }
(DNF)는 부울 표현식을 구성하는 표준 방식입니다. 구체적으로, 이는 부울 식을 일련의 ORed AND로 구조화하는 것을 의미합니다. 유형 선언에 적용하면 구문 분석기가 처리할 수 있는 결합 및 교차 유형을 작성하는 표준 방법을 사용할 수 있습니다.
예를 들어 이제 무효화 가능한 교차점 유형을 가질 수 있게 되었으니 큰 변화입니다:
함수 getFullName((HasName&HasSurname)|null $user) { ... }
저는 특성을 사용하는 것을 별로 좋아하지 않으며, 특히 오브젝트를 초기화하지 않고 특성 값을 사용할 수 없기 때문에 이러한 변경은 순전히 외관상의 문제일 뿐입니다.
특성 Foo {
public const FLAG_1 = 1;
protected const FLAG_2 = 2;
private const FLAG_3 = 2;
public function doFoo(int $flags): void {
if ($flags & self::FLAG_1) { {
echo 'Got flag 1';
}
if ($flags & self::FLAG_2) {
echo 'Got flag 2';
}
if ($flags & self::FLAG_3) {
echo 'Got flag 3';
}
}
}
제가 가장 기대하는 가장 중요한 변화 중 하나입니다. 최신 버전의 PHP에서는 변수를 다음과 같이 표시할 수 있습니다. 민감한 매개변수 값
. 왜 그래야 할까요?
PHP의 예외 스택 추적은 디버깅에 매우 유용하지만, 매개변수 값을 미리 볼 수 있습니다. 예를 들어 PDO 코드 를 사용하여 데이터베이스에 연결합니다. 디버그 추적은 다음과 같습니다:
PDOException: SQLSTATE[HY000] [2002] /var/www/html/test.php:3에 해당 파일 또는 디렉터리가 없습니다.
스택 추적:
#0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 {메인}
주석 사용 후 #[민감한 매개변수]
스택 추적에 더 이상 변수 값이 표시되지 않습니다.
함수 테스트(
$foo,
#[민감 파라미터] $bar,
$baz
) {
새로운 예외('Error')를 던집니다;
}
test('foo', 'bar', 'baz');
/*
치명적인 에러입니다: 잡히지 않은 예외입니다: test.php:8에 오류가 발생했습니다.
스택 추적:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {메인}
8줄의 test.php에 던져짐
*/
As 저자 말한다
이 변경의 주된 동기는 배열 키와 같이 열거형 객체가 허용되지 않는 위치에서 이름 및 값 속성을 가져올 수 있도록 허용하기 위해서입니다. 배열에서 작업하여 열거형이나 모든 객체를 키로 허용하도록 확장할 수도 있지만 열거형의 프로퍼티를 가져올 수 있도록 허용하는 것이 더 간단합니다.
enum A: 문자열 {
case B = 'B';
const C = [self::B->value => self::B];
}
이전에는 정적 메서드가 이와 같이 작동했습니다:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
In PHP 8.2 로 변경될 예정입니다:
DateTime::createFromImmutable(): static
DateTimeImmutable::createFromMutable(): static
이는 라이브러리 제작자 및/또는 모든 사용자 정의 DateTime 구현에 있어 획기적인 변화입니다.
이 두 가지 기능은 다음 두 가지 사이에서만 변환하기 때문에 목적에 부합하지 않았습니다. ISO-8859-1
그리고 UTF-8
. PHP 설명서에서 다음을 사용하는 것이 좋습니다. MB_Convert_encoding
대신
로캘 민감도는 RFC 작성자가 가장 잘 설명합니다:
PHP 8.0 이전에는 PHP의 로캘이 환경설정에서 설정되었습니다. 사용자가 Linux를 설치할 때 어떤 언어로 설치할지 묻는 메시지가 표시됩니다. 사용자는 이 결정의 결과를 충분히 이해하지 못할 수도 있습니다. 기본 제공 명령에 대한 사용자 인터페이스 언어를 설정할 뿐만 아니라 C 라이브러리의 문자열 처리 방식도 광범위하게 변경됩니다. 예를 들어 Linux를 설치할 때 "터키어"를 선택한 사용자는 toupper('i')를 호출하는 애플리케이션이 점선으로 된 대문자 I(U+0130, "İ")를 가져온다는 것을 알 수 있습니다.
표준화된 텍스트 기반 프로토콜의 시대에 자연어는 대소문자 변환을 위한 소수의 애플리케이션입니다. 그러나 사용자가 자연어 대소문자 변환을 원한다고 해도 strtolower()로는 성공하기 어려울 것입니다. 한 번에 한 바이트씩 문자열을 처리하여 각 바이트를 C 라이브러리의 tolower()에 공급하기 때문입니다. 입력이 현재 가장 많이 사용되는 UTF-8인 경우, strtolower()는 문자열을 뒤섞어서 일반적으로 잘못된 UTF-8을 출력으로 생성합니다.
PHP 8.0은 로캘 환경 변수를 더 이상 지원하지 않습니다. 따라서 사용자가 명시적으로 setlocale()을 호출하지 않는 한 로캘은 항상 "C"입니다. 즉, 이전 버전과 호환되지 않는 변경 사항의 대부분은 이미 사라졌습니다. 시스템 로캘에 따라 레거시 8비트 문자 집합의 대소문자 변환을 수행하는 모든 애플리케이션은 PHP 8.0에서 중단되었을 것입니다.
즉, 아래의 모든 함수는 PHP.8.2부터 ASCII 대소문자 변환을 수행한다는 의미입니다:strtolower
, strtoupper
, stristr
, stripos
, strripos
, lcfirst
, ucfirst
, ucwords
, str_ireplace
PHP에는 문자열에 변수를 삽입하는 다양한 방법이 있습니다:
- 변수 직접 임베딩("$foo")
- 변수 외부의 중괄호("{$foo}")
- 달러 기호 뒤의 중괄호("${foo}")
- 가변 변수("${expr}", (문자열) ${expr}에 해당)
혼동과 오용을 방지하기 위해 더 이상 작동하지 않습니다:
"Hello ${world}";
폐지되었습니다: 문자열에 ${}를 사용하는 것은 더 이상 사용되지 않습니다.
"Hello ${(world)}";
폐지되었습니다: 문자열에 ${}(가변 변수)를 사용하는 것은 더 이상 사용되지 않습니다.
이 변경 사항이 전부는 아닙니다. PHP 8.2 가 제공할 것입니다. 안타깝게도 아직 제네릭 유형에 대한 지원은 이루어지지 않았는데, 이는 단형화된 제네릭이 너무 많은 성능 오버헤드를 추가하고 재정의된 제네릭은 전체 코드베이스에 걸쳐 많은 변경이 필요하다는 Nikita의 말에 따른 것이었습니다. 그러나 눈에 띄는 점은 바로 제품. 이후 버전의 언어에 도입된 변경 사항은 점점 더 명확해지고 있으며, 관심 있는 분들은 다음과 같은 사실을 알게 될 것입니다. PHP 는 구문 간소화 및 새로운 기능 지원 분야에서 올바른 방향으로 나아가고 있습니다. 빠르면 내년 초에는 호출 가능
를 유효한 유형으로 입력합니다.