<?php
class Base {
public function a() {}
protected function b() {}
private function c() {}
}
trait Logs {
public function log(string $message): void {}
}
class Child extends Base {
use Logs { log as protected writeLog; }
public function test(): void {
$this->a(); // OK
$this->b(); // OK
// $this->c(); // Not accessible: private to Base
$this->writeLog('ok'); // OK inside class, protected alias
}
}
$child = new Child();
$child->a();
// $child->b(); // Not accessible from outside
// $child->writeLog('x'); // Not accessible from outside
<?php
trait JsonLogger {
public function log(string $message): void {
echo "json:$message\n";
}
}
trait FileLogger {
public function log(string $message): void {
echo "file:$message\n";
}
}
class Service {
use JsonLogger, FileLogger {
JsonLogger::log insteadof FileLogger;
FileLogger::log as logToFile;
JsonLogger::log as protected logJson;
}
}
$service = new Service();
$service->log('hello');
$service->logToFile('hello');
// $service->logJson('hello'); // not accessible from outside; protected alias
8スカラー型、nullable 型、直交型(union 型)、交差型(intersection 型)、および DNF (Disjunctive Normal Form) 型は PHP の API 契約をどのように表現し、それぞれどのような状況で使用すべきですか?
PHP の型宣言は、API が受け取る値や返す値を規定します。`int`、`float`、`string`、`bool` などのスカラー型は、単一のプリミティブな型のみが期待される場合に使用されます。`?T` や `T|null` と記述される nullable 型は、`T` 型の値または `null` のいずれかを許容します。`A|B` などの union 型は、複数の候補のうちいずれか1つを許容します。`A&B` などの intersection 型は、指定されたすべての型を満たすことを値に要求し、一般的に複数のインターフェイスを満たす必要がある場合に使用されます。DNF 型は、`(A&B)|C` のように union 型と intersection 型を組み合わせ、より複雑な契約を表現します。それぞれは、不要に広範または分かりにくい型を避け、実際の API の約束に合致する場合に使用すべきです。
<?php
interface Cacheable {}
class Report implements Cacheable, JsonSerializable {
public function jsonSerialize(): mixed { return []; }
}
function findName(int $id): ?string {
return $id > 0 ? 'Alice' : null;
}
function normalize(int|string $id): string {
return (string) $id;
}
function store(Cacheable&JsonSerializable $item): void {
// must satisfy both interfaces
}
function handle((Cacheable&JsonSerializable)|string $input): void {
// either an object satisfying both contracts, or a string
}
class Address {
public function __construct(public string $city) {}
}
class User {
public function __construct(public string $name, public Address $address) {}
public function __clone() {
$this->address = clone $this->address; // make nested object independent
}
}
$u1 = new User('Ann', new Address('Paris'));
$u2 = $u1; // same object handle
$u2->name = 'Beth';
echo $u1->name, PHP_EOL;
$u3 = clone $u1; // new User object; __clone deep-clones address
$u3->address->city = 'Rome';
echo $u1->address->city, PHP_EOL;
echo $u3->address->city, PHP_EOL;
Example:
- 6 application servers
- 40 PHP-FPM max_children per server
- 2 separate FPM pools that can hit the database
Potential concurrent PHP request DB connections = 6 * 40 * 2 = 480
If PostgreSQL max_connections is 300 and queues/cron/admin tools also connect,
connection exhaustion is expected during traffic spikes.