Liste aussi complète que possible pour PHP 8.x. Les exemples sont volontairement minimalistes.
Mots-clés et constructions de classe
class
Déclare une classe.
class User {}
$u = new User();
interface
Définit un contrat de méthodes publiques, sans implémentation.
interface Loggable { public function log(string $m): void; }
trait
Réutilisation d'implémentations entre classes.
trait TLog { public function log($m){ echo $m; } }
class A { use TLog; }
extends
Héritage de classe / d'interface.
class Admin extends User {}
interface B extends Loggable {}
implements
Indique qu'une classe s'engage à respecter l'interface.
class FileLogger implements Loggable {
public function log(string $m): void {}
}
abstract
Désigne une classe ou une méthode incomplète, destinée à être spécialisée.
abstract class Repo { abstract public function all(): array; }
final
Empêche l'héritage (classe) ou la surcharge (méthode).
final class UUID {}
class A { final public function id(){} }
public / protected / private
Visibilités des membres.
class C { public $a; protected $b; private $c; }
static (membre)
Membre rattaché à la classe, sans instance.
class C {
public static int $n = 0;
public static function v(){ return self::$n; }
}
static (retour)
Retourne le type appelant (liaison tardive).
class F { public function with(): static { return $this; } }
$this
Instance courante.
class C { function me(){ return $this; } }
self
Référence la classe dans laquelle le code est défini.
class A { public static function who(){ return __CLASS__; } }
parent
Accède aux membres de la classe parente.
class B extends A { public static function who(){ return parent::who(); } }
new
Instancie une classe (ou une classe anonyme).
$svc = new class { public function run(){} };
clone
Duplique un objet (appelle __clone()).
$u2 = clone $u;
instanceof
Teste le type objet.
if ($u2 instanceof User) { /* ... */ }
const (de classe)
Constante liée à la classe.
class C { public const VER = '1.0'; }
::class
Retourne le nom qualifié de la classe sous forme de chaîne.
$name = User::class; // "App\User" selon namespace
readonly (propriété)
Propriété assignable une seule fois (8.1+).
class C { public readonly int $id;
function __construct(int $id){ $this->id = $id; }
}
readonly class
Indique que toutes les propriétés sont readonly (8.2+).
readonly class D { public int $id; }
use (trait)
Importe un trait dans une classe.
class L { use TLog; }
insteadof (trait)
Résout les conflits de méthodes entre traits.
trait A{ function x(){echo 'A';} }
trait B{ function x(){echo 'B';} }
class C{ use A,B { A::x insteadof B; } }
as (trait)
Alias (et changement de visibilité possible).
class C{ use A { x as public xAlias; } }
enum
Type énuméré orienté objet (8.1+).
enum Status:string { case Ok='ok'; case Ko='ko'; }
__construct()
Constructeur.
class U { function __construct(public string $n) {} }
Méthodes magiques
__destruct()
Nettoyage à la destruction.
class U { function __destruct(){ /* cleanup */ } }
__get() / __set()
Permet d'accéder à des propriétés inaccessibles ou de leur affecter une valeur.
function __get($n){ /* ... */ }
function __set($n,$v){ /* ... */ }
__isset() / __unset()
Support de isset() / unset().
function __isset($n){ return false; }
function __unset($n){ /* ... */ }
__call()
Appel d'une méthode d'instance inexistante.
function __call($name, $args){ /* proxy */ }
__callStatic()
Appel d'une méthode statique inexistante.
public static function __callStatic($n,$a){ /* ... */ }
__toString()
Conversion en chaîne.
function __toString(){ return 'User#1'; }
__invoke()
Rend l'objet appelable comme une fonction.
function __invoke($x){ return $x + 1; }
__sleep() / __wakeup()
Ancienne API de sérialisation ; privilégiez __serialize().
function __sleep(){ return ['id']; }
function __wakeup(){ /* ... */ }
__serialize() / __unserialize()
API moderne de (dé)sérialisation.
function __serialize(){ return ['id' => $this->id]; }
function __unserialize($d){ $this->id = $d['id']; }
__set_state()
Reconstruction via var_export().
public static function __set_state($a){ return new self(); }
__debugInfo()
Personnalise var_dump().
function __debugInfo(){ return ['id' => $this->id]; }
__clone()
Personnalise le clonage.
function __clone(){ $this->id = null; }
Namespaces, types et patterns
namespace
Permet d'organiser les classes.
namespace App;
class User {}
use (namespace)
Importe un nom qualifié ou définit un alias.
use App\User as U;
$u = new U();
Type object
Type générique indiquant « un objet ».
function f(object $o): object { return $o; }
Promotion de propriétés
Déclare la propriété, son type et sa visibilité directement dans le constructeur.
class P { function __construct(public int $id) {} }
Classe anonyme
Définie directement au point d'usage.
$svc = new class { public function run(){} };
Constantes magiques
Métadonnées utiles.
__CLASS__, __METHOD__, __TRAIT__, __NAMESPACE__
(object)[] / stdClass
Convertit un tableau (ou null) en objet : crée une instance de stdClass, objet générique acceptant des propriétés dynamiques.
$a = (object)[]; // <=> $a = new stdClass();
$a->foo = 'bar';
Opérateur nullsafe ?->
Accède à une propriété ou une méthode uniquement si l'objet n'est pas null, sinon retourne null.
$city = $user?->profile?->address?->city ?? 'N/A';
static:: (liaison statique tardive)
Se résout vers la classe réellement appelée, et non vers celle où le code est écrit ; utile en héritage.
class A { public static function who(){ return static::class; } }
class B extends A {}
echo B::who(); // "B"
Interfaces SPL et fonctionnalités
JsonSerializable
Contrôle le JSON produit par json_encode().
class U implements JsonSerializable {
public function __construct(private int $id) {}
public function jsonSerialize(): mixed { return ['id' => $this->id]; }
}
echo json_encode(new U(1)); // {"id":1}
ArrayAccess
Permet d'accéder à l'objet comme à un tableau.
class Bag implements ArrayAccess {
private array $d = [];
public function offsetSet($k,$v):void{ $this->d[$k]=$v; }
public function offsetGet($k):mixed{ return $this->d[$k]??null; }
public function offsetExists($k):bool{ return isset($this->d[$k]); }
public function offsetUnset($k):void{ unset($this->d[$k]); }
}
$b = new Bag; $b['foo']='bar';
Countable
Autorise count($obj) sur votre objet.
class C implements Countable { public function count(): int { return 42; } }
echo count(new C); // 42
IteratorAggregate
Autorise foreach sur votre objet, avec une mise en oeuvre plus simple qu'une implémentation directe de Iterator.
class Collection implements IteratorAggregate {
public function __construct(private array $items){}
public function getIterator(): Traversable { yield from $this->items; }
}
foreach (new Collection([1,2,3]) as $v) {}
Stringable
Interface de type pour les objets convertibles en chaîne ; elle est satisfaite si __toString() existe.
class U { public function __toString(){ return 'U#1'; } }
function f(Stringable $s){ echo (string)$s; }
f(new U());
WeakMap / WeakReference
Associe des métadonnées à des objets sans empêcher leur ramassage mémoire, ce qui limite les fuites.
$wm = new WeakMap();
$o = new stdClass();
$wm[$o] = 'meta';
unset($o); // l'entrée disparaît automatiquement
Attributs PHP #[...]
Ajoute des métadonnées déclaratives aux classes, propriétés ou méthodes.
#[Attribute] class Table { public function __construct(public string $name){} }
#[Table('users')] class User {}
#[AllowDynamicProperties]
Autorise (8.2+) les propriétés dynamiques sur une classe donnée (déconseillé).
#[AllowDynamicProperties]
class Legacy {}
$x = new Legacy; $x->foo = 'bar';
Closure::call()
Lie temporairement une closure à un objet, avec accès à son $this privé ou protégé.
$fn = function(){ return $this->secret; };
class Box { private string $secret='shh'; }
echo $fn->call(new Box()); // "shh"
ReflectionClass
Fournit des capacités d'introspection sur les objets : méthodes, propriétés, attributs, etc.
$r = new ReflectionClass(User::class);
$methods = array_map(fn($m)=>$m->getName(), $r->getMethods());
Patterns d'objets
Constructeurs nommés (pattern)
Remplace des new ambigus par des méthodes de création plus explicites.
final class Money {
private function __construct(private int $cents) {}
public static function fromCents(int $c): self { return new self($c); }
public static function fromFloat(float $v): self { return new self((int)round($v*100)); }
}
$m = Money::fromFloat(12.34);
Objets immuables (pattern)
Repose sur readonly et des méthodes with* qui retournent un nouvel objet.
readonly class Point { public function __construct(public int $x, public int $y){}
public function withX(int $x): self { return new self($x, $this->y); }
}
$p2 = (new Point(1,2))->withX(3);
Monostate : stockage static, accès via instance
L'état est partagé entre toutes les instances, mais exposé via un accesseur d'instance. Cela permet d'écrire $this->get() tout en conservant une unique valeur globale.
class A {
private static ?int $madonnee = null;
public function __construct() {
if (self::$madonnee === null) {
self::$madonnee = 123;
}
}
public function get(): int {
return self::$madonnee; // accès via $this->get()
}
}
PDO partagé (static) + getter d'instance
Connexion unique initialisée à la demande, stockée en static et exposée via $this->getPDO().
final class Database {
private static ?PDO $pdo = null;
public function getPDO(): PDO {
return self::$pdo ??= new PDO(
'mysql:host=localhost;dbname=xxx;charset=utf8mb4',
'user','pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
}
}
// usage : $req = $this->getPDO()->query($statement);
Version 100 % instance (sans static)
Chaque objet gère son propre état, ce qui améliore la testabilité et l'injection. Cette approche convient si vous souhaitez éviter l'état global et faciliter les doublures de test.
final class Database {
private ?PDO $pdo = null;
public function getPDO(): PDO {
return $this->pdo ??= new PDO(
'mysql:host=localhost;dbname=xxx;charset=utf8mb4',
'user','pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
}
}
Interfaces : contrat et découplage
Pourquoi les interfaces (contrat et découplage)
Elles définissent un contrat sans implémentation. Elles favorisent le polymorphisme, la substitution (remplacer une implémentation par une autre), le découplage (DIP/IoC) et des tests plus simples (mocks/fakes).
interface Logger { public function log(string $m): void; }
class FileLogger implements Logger { public function log(string $m): void {/*...*/} }
class NullLogger implements Logger { public function log(string $m): void {/* noop */} }
function run(Logger $log){ $log->log('hello'); } // n'accepte que le contrat
run(new FileLogger());
run(new NullLogger()); // interchangeable
Interface qui extends plusieurs interfaces
Une interface peut étendre plusieurs contrats.
interface A { public function a(): void; }
interface B { public function b(): void; }
interface C extends A, B {} // héritage multiple d'interfaces
class X implements C {
public function a(): void {}
public function b(): void {}
}
Classe qui implements plusieurs interfaces
Une classe peut satisfaire plusieurs contrats simultanément.
interface CsvExport { public function toCsv(): string; }
interface JsonExport{ public function toJson(): string; }
class Report implements CsvExport, JsonExport {
public function toCsv(): string { return "a;b"; }
public function toJson(): string { return '{"a":"b"}'; }
}
Constantes et méthodes static dans une interface
Les interfaces peuvent définir des constantes et des signatures statiques.
interface Versioned {
public const VER = '1.0';
public static function build(): self; // signature statique
}
class Lib implements Versioned {
public static function build(): self { return new self(); }
}
Types de retour self et static en interface
self désigne l'implémentation ; static correspond à la liaison tardive, utile notamment pour les API fluentes.
interface Fluent {
public function with(string $k, mixed $v): static; // fluent
public static function make(): self; // fabrique
}
class Bag implements Fluent {
public static function make(): self { return new self(); }
public function with(string $k, mixed $v): static { return $this; }
}
Variance (retour covariant, paramètre contravariant)
Le retour peut être plus spécifique ; le paramètre peut être plus large.
// Retour covariant
interface Factory { public function make(): Traversable; }
class ItFactory implements Factory { public function make(): Iterator { return new ArrayIterator([]); } }
// Paramètre contravariant
interface Handler { public function handle(Traversable $it): void; }
class H implements Handler { public function handle(iterable $it): void {} } // plus large
Types union / intersection avec interfaces
Permet de composer les contrats en union (|) ou en intersection (&) (PHP 8.0/8.1+).
interface A { public function a(): void; }
interface B { public function b(): void; }
function useEither(A|B $x): void { /* ... */ } // union
interface Both { public function set(A&B $x): void; } // intersection
Dépendance sur interface (DI/IoC)
Le type-hint sur l'interface favorise le découplage et facilite les tests.
interface Cache { public function get(string $k): mixed; }
class Service {
public function __construct(private Cache $cache) {}
}
Interface + Trait (implémentation par défaut)
On déclare le contrat dans l'interface et on fournit une implémentation réutilisable via un trait.
interface Loggable { public function log(string $m): void; }
trait DefaultLog { public function log(string $m): void { /* write */ } }
class Svc implements Loggable { use DefaultLog; }
instanceof sur une interface
Vérifie à l'exécution si un objet satisfait un contrat donné.
if ($obj instanceof Psr\Log\LoggerInterface) { $obj->info('ok'); }
Fabrique qui retourne une interface
Masque le choix d'implémentation derrière un point d'entrée unique.
interface Transport { public function send(string $data): void; }
class HttpTransport implements Transport { public function send(string $d): void {} }
class AmqpTransport implements Transport { public function send(string $d): void {} }
final class TransportFactory {
public static function create(string $dsn): Transport {
return str_starts_with($dsn, 'amqp:') ? new AmqpTransport() : new HttpTransport();
}
}
$t = TransportFactory::create($dsn); $t->send('payload');
Ségrégation des interfaces (ISP)
Mieux vaut plusieurs interfaces ciblées qu'une interface monolithique de type « god object ».
interface Reads { public function read(): string; }
interface Writes { public function write(string $d): void; }
class FileIO implements Reads, Writes {
public function read(): string {/*...*/}
public function write(string $d): void {/*...*/}
}
Règles d'une interface (visibilité & contenu)
Les méthodes sont implicitement publiques (pas de private/protected). Une interface ne peut pas définir de propriétés d'instance ; elle peut définir des constantes et des signatures (y compris __construct()).
interface Port {
public const VER = '1.0';
public function open(): void; // public implicite
public function __construct(string $dsn); // OK (sera public)
}
Interface vs classe abstraite (quand choisir ?)
Interface = contrat pur ; classe abstraite = contrat, implémentation partielle et éventuel état. Si vous partagez du code ou de l'état, préférez l'abstraite ; sinon, l'interface reste plus adaptée.
interface Hash { public function make(string $v): string; }
abstract class BaseRepo {
protected PDO $pdo; // état partagé
public function __construct(PDO $pdo){ $this->pdo = $pdo; }
abstract public function all(): array; // contrat
protected function map(array $r): object {/*...*/} // implémentation partielle
}
Enums qui implémentent une interface
Un enum peut satisfaire un contrat, idéal pour garantir un comportement sur chaque case.
interface Jsonable { public function toJson(): string; }
enum Status: string implements Jsonable {
case Ok = 'ok'; case Ko = 'ko';
public function toJson(): string { return json_encode($this->value); }
}
echo Status::Ok->toJson(); // "ok"
Standards d'interop (PSR)
Les interfaces PSR facilitent l'interopérabilité entre bibliothèques (logger, conteneur, cache, HTTP, événements...).
use Psr\Log\LoggerInterface;
class Service {
public function __construct(private LoggerInterface $log) {}
public function run(): void { $this->log->info('ok'); }
}
Décorateur / Proxy basé sur interface
Ajoute des comportements sans modifier l'implémentation d'origine ; la composition est ici préférable à l'héritage.
interface Repo { public function find(int $id): object; }
final class SqlRepo implements Repo { public function find(int $id): object {/*...*/} }
final class CachedRepo implements Repo {
public function __construct(private Repo $inner) {}
public function find(int $id): object { /* cache autour de $inner */ return $this->inner->find($id); }
}
Chaîne de responsabilité / Middleware
Compose plusieurs traitements en pipeline à partir d'un contrat commun.
interface Middleware {
public function handle(Request $r, callable $next): Response;
}
final class Auth implements Middleware {
public function handle(Request $r, callable $next): Response { /* ... */ return $next($r); }
}
Tests unitaires : mocks sur interface
Moquer une interface découple les tests de l'implémentation concrète.
// PHPUnit
$logger = $this->createMock(Psr\Log\LoggerInterface::class);
$logger->expects($this->once())->method('info');
$svc = new Service($logger); $svc->run();
Génériques (docblocks) avec interfaces
Simule des types génériques pour l'analyse statique (Psalm/PHPStan) au moyen de @template et @implements.
/** @template T */
/** @implements IteratorAggregate<T> */
interface ReadonlyList extends IteratorAggregate {}
/** @template T */
final class ArrayList implements ReadonlyList {
/** @param list<T> $items */ public function __construct(private array $items) {}
/** @return Traversable<T> */ public function getIterator(): Traversable { yield from $this->items; }
}
Intersection & union avec interfaces (rappel)
Exiger plusieurs contrats à la fois (intersection) ou en accepter plusieurs (union).
interface A { public function a(): void; }
interface B { public function b(): void; }
function needsBoth(A&B $x): void { $x->a(); $x->b(); } // intersection
function useEither(A|B $x): void { /* ... */ } // union
Chaînage de méthodes (Fluent)
Fluent & constructeurs nommés typés sur interface
Des contrats plus expressifs grâce à static (fluent) et self (fabrique).
interface Builder {
public static function create(): self;
public function with(string $k, mixed $v): static;
}
Chaînage de méthodes (Fluent Interface)
Chaque méthode retourne $this pour enchaîner plusieurs appels de façon lisible.
class Query {
private array $where = [];
private int $limit = 0;
public function where(string $c): static { $this->where[] = $c; return $this; }
public function limit(int $n): static { $this->limit = $n; return $this; }
public function get(): array { /* ... */ return []; }
}
$rows = (new Query())->where('a=1')->limit(10)->get();
Typage de retour pour le chaînage : static vs self vs interface
static préserve le type réel en héritage, self fige la classe courante, et retourner une interface conserve davantage de souplesse.
interface Builder { public function with(string $k, mixed $v): static; }
class Base {
public function setA(int $a): static { return $this; } // <-- mieux pour sous-classes
}
class Child extends Base {
public function setB(int $b): static { return $this; }
}
$o = (new Child())->setA(1)->setB(2); // OK grâce à static
Chaînage immuable (méthodes *with**)
Au lieu de modifier l'objet, chaque appel retourne une nouvelle instance, ce qui sécurise l'état.
readonly class Money {
public function __construct(public int $cents) {}
public function withCents(int $c): self { return new self($c); }
}
$m2 = (new Money(100))->withCents(250); // $m original inchangé
Pattern Builder (chaînage jusqu'à build())
Accumule des options via chaînage puis produit un objet final valide.
final class HttpRequest {
public function __construct(public string $url, public array $headers = []) {}
}
final class RequestBuilder {
private string $url = '';
private array $headers = [];
public static function create(): self { return new self(); }
public function url(string $u): static { $this->url = $u; return $this; }
public function header(string $k, string $v): static { $this->headers[$k] = $v; return $this; }
public function build(): HttpRequest { return new HttpRequest($this->url, $this->headers); }
}
$req = RequestBuilder::create()
->url('https://api.local')
->header('Accept','application/json')
->build();
Introspection : fonctions *_exists et réflexion
function_exists()
Vérifie si une fonction est définie.
if (function_exists('mb_strtolower')) {
$s = mb_strtolower($s);
}
method_exists()
Vérifie si une méthode existe sur un objet ou une classe.
if (method_exists($obj, 'run')) {
$obj->run();
}
property_exists()
Teste l'existence d'une propriété (même si null).
if (property_exists($obj, 'id')) {
echo $obj->id;
}
class_exists()
Vérifie si une classe est déclarée (option d'autoload).
if (class_exists(App\Service::class)) {
$s = new App\Service();
}
interface_exists()
Vérifie si une interface est déclarée (option d'autoload).
if (interface_exists(Psr\Log\LoggerInterface::class)) {
// ...
}
trait_exists()
Vérifie si un trait est déclaré.
if (trait_exists(App\TLog::class)) {
// ...
}
enum_exists() (8.1+)
Vérifie si un enum est déclaré.
if (enum_exists(App\Status::class)) {
$st = App\Status::Ok;
}
is_callable()
Teste si une valeur est appelable (closure, [$obj,'meth'], etc.).
$cb = [$obj, 'handle'];
if (is_callable($cb)) {
$cb('data');
}
is_a()
Vérifie si un objet (ou nom de classe) est d'un type donné.
if (is_a($obj, App\User::class)) { /* ... */ }
is_subclass_of()
Vérifie qu'un type est une sous-classe d'un autre.
if (is_subclass_of(App\Admin::class, App\User::class)) { /* ... */ }
get_class()
Retourne le nom de la classe d'un objet.
echo get_class($obj); // "App\User"
get_parent_class()
Retourne la classe parente d'un objet/nom de classe.
echo get_parent_class(App\Admin::class); // "App\User"
get_class_methods()
Liste les méthodes d'une classe/objet.
$methods = get_class_methods($obj);
get_class_vars()
Retourne les propriétés par défaut d'une classe.
$defaults = get_class_vars(App\User::class);
get_object_vars()
Retourne les propriétés accessibles d'un objet dans le contexte courant.
$props = get_object_vars($obj);
class_parents()
Renvoie toutes les classes parentes (tableau associatif).
$parents = class_parents($obj);
class_implements()
Renvoie les interfaces implémentées.
$ifaces = class_implements($obj);
class_uses()
Renvoie les traits utilisés par une classe/objet.
$traits = class_uses(App\Service::class);
get_declared_classes()
Liste toutes les classes déclarées.
$classes = get_declared_classes();
get_declared_interfaces()
Liste toutes les interfaces déclarées.
$ifaces = get_declared_interfaces();
get_declared_traits()
Liste tous les traits déclarés.
$traits = get_declared_traits();
get_declared_enums() (8.1+)
Liste tous les enums déclarés.
$enums = get_declared_enums();
get_defined_functions()
Retourne les fonctions définies (internes & utilisateur).
$fns = get_defined_functions();
Manipuler des collections d'objets
Parcours simple (foreach)
Permet d'itérer sur un tableau d'objets et d'accéder à leurs propriétés ou méthodes.
class User{ public function __construct(public int $id, public string $name){} }
$users = [new User(1,'Ana'), new User(2,'Bob')];
foreach ($users as $u) {
echo $u->id.' '.$u->name.PHP_EOL;
}
Filtrage (array_filter)
Conserve uniquement les objets qui satisfont un prédicat. Pensez à array_values() pour réindexer le résultat.
$adults = array_values(array_filter($users, fn($u) => $u->age >= 18));
Filtrage avec clés (ARRAY_FILTER_USE_BOTH)
Le callback reçoit la valeur et la clé (index).
$keepOddIdx = array_filter($users, fn($u,$i)=>$i%2===1, ARRAY_FILTER_USE_BOTH);
Mapping (array_map)
Transforme un tableau d'objets, par exemple pour extraire une propriété ou produire un DTO.
$names = array_map(fn($u) => $u->name, $users);
$rows = array_map(fn($u) => ['id'=>$u->id,'name'=>$u->name], $users);
Recherche (trouver le premier)
Récupère le premier objet correspondant, sans recourir à une double boucle.
function findFirst(array $items, callable $pred): ?object {
foreach ($items as $it) if ($pred($it)) return $it;
return null;
}
$bob = findFirst($users, fn($u)=>$u->name==='Bob');
Indexation par clé (lookup O(1))
Construit un tableau associatif indexé par une propriété, par exemple id.
$byId = [];
foreach ($users as $u) { $byId[$u->id] = $u; }
$user2 = $byId[2] ?? null;
Groupement (groupBy)
Regroupe les objets selon une propriété, par exemple l'âge.
function groupBy(array $items, callable $key): array {
$out = [];
foreach ($items as $it) { $out[$key($it)][] = $it; }
return $out;
}
$byAge = groupBy($users, fn($u)=>$u->age);
Tri (usort + <=>)
Trie par propriété, avec un critère secondaire en cas d'égalité.
usort($users, fn($a,$b) => ($a->age <=> $b->age) ?: strcasecmp($a->name,$b->name));
Réduction (somme/moyenne)
Agréger des valeurs dérivées des objets.
$totalAge = array_reduce($users, fn($acc,$u)=>$acc+$u->age, 0);
$avgAge = count($users) ? $totalAge / count($users) : 0;
Unicité par propriété
Déduplique à partir d'une clé dérivée, par exemple email.
function uniqueBy(array $items, callable $key): array {
$seen=[]; $out=[];
foreach ($items as $it) {
$k=$key($it);
if (isset($seen[$k])) continue;
$seen[$k]=true; $out[]=$it;
}
return $out;
}
$unique = uniqueBy($users, fn($u)=>$u->email);
Partition
Sépare les objets en deux groupes selon un prédicat, par exemple actifs et inactifs.
function partition(array $items, callable $pred): array {
$yes=[]; $no=[];
foreach ($items as $it) { ($pred($it) ? $yes : $no)[] = $it; }
return [$yes, $no];
}
[$active,$inactive] = partition($users, fn($u)=>$u->active);
Pagination / segment (array_slice)
Récupère une page d'objets à partir d'un couple offset/limit.
$page = 2; $per = 20; $offset = ($page-1)*$per;
$items = array_slice($users, $offset, $per);
Découpage fixe (array_chunk)
Découpe les données en lots de taille N pour un traitement par batch.
foreach (array_chunk($users, 100) as $batch) {
// traiter 100 objets à la fois
}
Transformations paresseuses (générateurs)
Permet des itérations lazy sur de gros volumes, sans tout charger en mémoire.
function filter(iterable $it, callable $p): iterable { foreach ($it as $x) if ($p($x)) yield $x; }
function map(iterable $it, callable $f): iterable { foreach ($it as $x) yield $f($x); }
$names = map(filter($users, fn($u)=>$u->age>=18), fn($u)=>$u->name);
foreach ($names as $n) { /* stream */ }
Identité objet (set/map) : SplObjectStorage
Gère une unicité fondée sur l'identité de l'objet, et non sur une propriété, avec des métadonnées associées.
$set = new SplObjectStorage();
foreach ($users as $u) { $set->attach($u, ['seen'=>true]); }
$exists = $set->contains($users[0]); // true
Extraction de colonnes (objets → tableau)
array_column() ne gère pas les objets ; utiliser array_map().
$ids = array_map(fn($u)=>$u->id, $users);
Clonage en masse
Duplique des objets de manière superficielle ; prévoyez __clone() si une copie profonde est nécessaire.
$copies = array_map(fn($u)=>clone $u, $users);
Sérialisation JSON
Encode un tableau d'objets ; implémentez JsonSerializable pour maîtriser la sortie.
echo json_encode($users, JSON_THROW_ON_ERROR); // appelle jsonSerialize() si dispo
Nettoyage des vides
Élimine null et false tout en conservant les 0 valides ; précisez un callback adapté.
$clean = array_values(array_filter($users, fn($u)=>$u !== null));