PHPの開発symfony コンソールコンポーネント - ヒントとコツ
この記事は、symfony コンソール開発に関するもっとも便利で検索しやすいヒントとトリックをお見せする目的で作成されました。
PHPの新バージョンは目前。あなたが知っておくべき新しい実装とは何でしょうか?この記事で確認してほしい!
PHP 8.2 がリリースされようとしている。おそらく、PHP 8へのアップグレードが誰にとっても魅力的に思えるバージョンになるだろう。では、開発者が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
class A {}
class B extends A {}
クラス Producer {
public function method():A {}
}
class ChildProducer extends Producer { {} }.
public function method():B {}
}
?>
<?php
$array['key'] ??= computeDefault();
// とほぼ等価である。
if (!isset($array['key'])){
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>
<?php
// オブジェクトに必要なすべての状態を含む配列を返します。
public function __serialize(): array;
// 与えられたデータ配列からオブジェクトの状態を復元します。
public function __unserialize(array $data): void;
?>
2020年11月にリリースされたPHP 8.0は、これまでで最高の機能をもたらした:
htmlspecialchars($string、double_encode: false);。
クラス PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])].
public function get($id) { /* ...*/ }
}
クラス Point {
public function __construct(
public float $x = 0.0、
public float $y = 0.0、
public float $z = 0.0、
){}
}
クラス Number {
public function __construct(
private int|float $number
){}
}
new Number('NaN'); // 型エラー
エコーマッチ (8.0) {
'8.0' => "Oh no!
8.0 => "予想通り"、
};
//> これが私の予想です
$country = $session?->user?->getAddress()?->country;
列挙ステータス
{
case Draft;
ケース 公開
case Archived;
}
function acceptStatus(Status $status) {...}.
クラス BlogData
{
public readonly Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
クラス・サービス
{
private Logger $logger;
public function __construct(
Logger $logger = new NullLogger()、
){
$this->logger = $logger;
}
}
関数 count_and_iterate(Iterator&Countable $value) { { count_and_iterate(Iterator&Countable $value)
foreach($valueを$valとする) { { echo $val; $val
echo $val;
}
count($value);
}
$response = $httpClient->request('https://example.com/');
print json_decode($response->getBody()->buffer())['code'];
PHP 8.2 は、開発者の生活をより簡単にし、作業をさらに最適化することを目的としたさらなる変更を導入している。以下は新機能のリストである。
新バージョンのPHPの最大の改良点の1つは リードオンリー
クラスに適用されます。この機能で記述されたクラスは、自動的にその変数に伝搬します。DTOクラスはこれですっきりとした見た目になります!
読み取り専用クラス InvoiceDTO
{
public function __construct(
public UUID $uuid、
public Issuer $issuer、
public DateTime $issuedAt、
){}
}
つ目の大きな変更点は、クラス内の動的変数が非推奨になったことだ。以下の実装では PHP 8.2 そして エラー例外
PHPの将来のバージョンでは
クラス MyUser
{
public string $name;
}
(...)
$myUser->name = 'Name'; // OK
$myUser->surname = 'Surname'; // 非推奨/エラー例外
を実装しているクラスは __get
そして __セット
のメソッドとクラスを直接継承している。 標準クラス
は、何の障害もなくマジックメソッドを実装することができる。
こちらも参照されたい。 GitHubの興味深いスレッドここでは、PHP-CSの開発者がこの変更と、新バージョンの言語用に人気のツールを変更する必要性について議論している。
最後になるが、アノテーションでこの動作を無効にすることができる。
#[AllowDynamicProperties](アローダイナミックプロパティ
クラス MyUser
{
public string $name;
}
$myUser->surname = 'Surname'; // OK
ヌル
, 真の
そして 擬似
これまでは 真の
または 擬似
値を記述しなければならなかった。 ブール
タイプだ。
function alwaysTrue(): bool { return true; }.
今後は 真の
そして 擬似
を関数の戻り値の単純型として使用する。
function alwaysTrue(): true { return true; }.
(DNF)は、ブール式を整理する標準的な方法である。具体的には、ブーリアン式をOR化された一連のANDに構造化することを意味する。型宣言に適用すると、パーサーが扱えるUnion型とIntersection型を組み合わせた標準的な記述方法が可能になる。
これは大きな変更で、例えば、NULL可能な交点型を持つことができるようになった:
function getFullName((HasName&HasSurname)|null $user) { ...}
特に、オブジェクトを初期化せずにTraitの値を使うことができないからだ。
フー
public const FLAG_1 = 1;
protected const FLAG_2 = 2;
private const FLAG_3 = 2;
public function doFoo(int $flags): void { もし ($flags & self::FLAG_1)
if ($flags & self::FLAG_1) {
echo 'フラグ1を取得';
}
if ($flags & self::FLAG_2) { echo 'フラグ2を取得しました。
echo 'フラグ 2 を取得';
}
if ($flags & self::FLAG_3) { echo 'フラグ3を取得しました。
echo 'フラグ 3 を取得しました';
}
}
}
私が楽しみにしている最も重要な変更の一つです。PHPの最新バージョンでは、変数を次のようにマークできるようになります。 SensitiveParameterValue
.なぜそうしなければならないのか?
PHP の例外発生時のスタックトレースはデバッグに非常に便利ですが、 パラメータの値をプレビューすることができます。たとえば、PDO コード データベースへの接続に使用される。デバッグ・トレースは以下のようになる:
PDOException:SQLSTATE[HY000] [2002] そのようなファイルまたはディレクトリがありません in /var/www/html/test.php:3
スタックトレース:
#0 /var/www/html/test.php(3):PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 {main}
アノテーション使用後 #[SensitiveParameter](センシティブ・パラメータ
スタック・トレースには変数の値が表示されなくなる。
関数 test(
$foo、
#[SensitiveParameter]$bar、
$baz
) {
throw new Exception('エラー');
}
test('foo', 'bar', 'baz');
/*
致命的なエラー:捕捉されない例外:エラー in test.php:8
スタックトレース:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
8行目のtest.phpでスローされています。
*/
として 著者は言う。
この変更の主な動機は、配列のキーのように、enumオブジェクトが許可されていない場所で名前と値のプロパティをフェッチできるようにすることです。配列を拡張して、enumやすべてのオブジェクトをキーとして使用できるようにすることもできますが、enumのプロパティをフェッチできるようにする方が簡単です。
enum A: 文字列 {
case B = 'B';
const C = [self::B->value => self::B];
}
以前の静的メソッドは次のように動作していた:
DateTime::createFromImmutable():DateTime
DateTimeImmutable::createFromMutable(): DateTime:DateTimeImmutable
で PHP 8.2 に変更される:
DateTime::createFromImmutable(): static
DateTimeImmutable::createFromMutable(): static
これは、ライブラリの作成者やDateTimeのすべてのカスタム実装にとって画期的な変更です。
の間で変換するだけで、この2つの機能は目的を果たせなかった。 ISO-8859-1
そして UTF-8
.PHP マニュアル mb_convert_encoding
その代わりだ。
ロケール感度については、RFCの著者が最もよく説明している:
PHP 8.0以前では、PHPのロケールは環境から設定されていました。ユーザがLinuxをインストールするとき、どの言語にするか尋ねられます。ユーザーは、この決定がもたらす結果を十分に理解していないかもしれません。このロケールは、組み込みコマンドのユーザーインターフェイス言語を設定するだけでなく、Cライブラリでの文字列処理の動作も広く変更します。例えば、Linuxのインストール時に「トルコ語」を選択したユーザーは、toupper('i')を呼び出すアプリケーションがドット付き大文字のI(U+0130、"İ")を取得することに気づくだろう。
標準化されたテキストベースのプロトコルの時代において、自然言語は大文字小文字変換の少数派アプリケーションである。しかし、たとえユーザーが自然言語の大文字小文字変換を望んでいたとしても、strtolower()で成功する可能性は低いだろう。これは、文字列を1バイトずつ処理し、各バイトをCライブラリのtolower()に送るからである。入力がUTF-8である場合、strtolower()は文字列を混乱させ、通常、出力として無効なUTF-8を生成する。
PHP 8.0がロケール環境変数を尊重しなくなった。そのため、ユーザーが明示的にsetlocale()を呼び出さない限り、ロケールは常に "C "となる。つまり、後方互換性の変更の大部分はすでに過去のものとなっているのです。システムロケールに依存してレガシー8ビット文字セットの大文字小文字変換を行っていたアプリケーションは、PHP 8.0によって壊れてしまっただろう。
つまり、以下の関数はすべてPHP.8.2からのASCII大文字小文字変換を行う:ストロートロワー
, ストッパー
, ストリスト
, ストリップ
, ストリップス
, エルシーファースト
, 最初
, ユーシーワード
, str_ireplace
PHPでは、文字列に変数を埋め込む方法がたくさんあります:
- 変数の直接埋め込み ("$foo")
- 変数の外側の中括弧 ("{$foo}")
- ドル記号の後の中括弧 ("${foo}")
- 変数変数 ("${expr}"、(文字列) ${expr} と等価)
混乱や誤用を避けるため、これらはもう使えない:
"こんにちは ${世界}";
非推奨:文字列での${}の使用は非推奨です。
"こんにちは ${(world)}";
非推奨:文字列での ${} (変数変数) の使用は非推奨です。
これらの変更点はすべてではない。 PHP 8.2 が提供してくれるだろう。残念なことに、ジェネリック型のサポートはまだ得られていない。ニキータが言うには、単型化されたジェネリック型はパフォーマンスのオーバーヘッドを増やしすぎるし、再型化されたジェネリック型はコードベース全体にわたって多くの変更を必要とするとのことだ。しかし注目すべきは、その規律とビジョンだ。 製品.歴代のバージョンで導入された変更点は明らかになりつつある。 PHP は、構文の簡素化と新規性のサポートの両面で正しい方向に進んでいる。早ければ来年には 呼び出し可能
を有効な型とする。