About Me
Two-Part Journey
Part 1
Part 2
Definition
PHP Gives Us
Special hooks PHP calls when normal object access needs custom behavior.
final class Profile
{
private array $data = [];
public function __get(string $key): mixed {}
public function __set(string $key, mixed $value): void {}
public function __call(string $method, array $arguments): bool {}
}
$profile = new Profile;
$profile->admin = true; // __set
$profile->admin; // __get
$profile->isAdmin(); // __call
Runtime APIs for inspecting classes, methods, properties, parameters, and metadata.
final class WelcomeEmail
{
public function __construct(
public string $subject,
private bool $urgent = false,
) {}
public function send(string $to): void {}
}
$class = new ReflectionClass(WelcomeEmail::class);
$constructor = $class->getConstructor();
$send = $class->getMethod('send');
$constructor->getParameters(); // subject, urgent
$class->newInstanceArgs(['Hello']); // WelcomeEmail
Structured metadata attached to code; behavior appears when runtime code reads it.
#[Attribute(Attribute::TARGET_CLASS)]
final class Audit
{
public function __construct(public string $stream) {}
}
#[Audit('orders')]
final class OrderPlaced {}
$attribute = new ReflectionClass(OrderPlaced::class)
->getAttributes(Audit::class)[0]
->newInstance();
Rebind a closure so $this and visibility scope point at another object.
final class Formatter
{
private string $style = 'loud';
}
$format = function (string $text): string {
return $this->style === 'loud'
? strtoupper($text)
: $text;
};
$format = $format->bindTo(new Formatter, Formatter::class);
$format('laradrome'); // LARADROME
Eloquent
$post->title;
$post->author;
Post::published()->latest()->get();
Eloquent Property Read
1. Magic Method
$post->title
2. Dynamic Dispatch
getAttribute()
3. Metadata Maps
$attributes / casts()
4. Runtime Pipeline
transformModelValue()
5. Domain Feel
int | string | Carbon | object
Eloquent Query Execution
Post::published()->latest()->get();
1. Static Magic
Model::__callStatic
2. Attribute Scope
#[Scope] published()
3. Builder Call
static::query()
4. Builder Magic
Builder::__call
5. Chain + Execute
latest()->get()
6. Hydrate
hydrate() → Collection
Facades
Cache::remember('stats', 60, fn () => $analytics->summary());
Cache::expects('remember')->once();
Facade Call Flow
1. Static Call
Cache::remember()
2. Magic Method
Facade::__callStatic
3. Accessor
getFacadeAccessor()
4. Container Key
'cache'
5. Root Object
$app['cache']
6. Forward Call
$instance->remember()
Facade Source Shape
class Cache extends Facade
{
protected static function getFacadeAccessor()
{
return 'cache';
}
}
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
return $instance->$method(...$args);
}
Macros
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
Collection::macro('toUpper', function () {
return $this->map(fn (string $value) => Str::upper($value));
});
collect(['laravel', 'php'])->toUpper();
Macro Dispatch Flow
1. Register
macro($name)
2. Registry
static::$macros
3. Dynamic Call
$collection->toUpper()
4. Magic Method
__call()
5. Closure Binding
bindTo($this)
6. Execute
$macro(...$args)
Laravel 13
Attribute Lifecycle
Laravel 13 Attribute Surface
70+
framework attributes
Eloquent And Resources
Available here
Table, Scope, ScopedBy, ObservedBy, UsePolicy, UseFactory, UseResource, UseResourceCollection, CollectedBy, Fillable, Hidden, Visible...
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Attributes\Table;
#[Table('blog_posts', key: 'uuid', keyType: 'string', incrementing: false)]
final class Post extends Model
{
#[Scope]
protected function published(Builder $query): void
{
$query->whereNotNull('published_at');
}
}
Container And Injection
Available here
Singleton, Scoped, Bind, Give, Config, Cache, Storage, Database, DB, Auth, CurrentUser, RouteParameter, Tag, Context...
use Illuminate\Container\Attributes\Config;
use Illuminate\Container\Attributes\Storage;
final class ReportExporter
{
public function __construct(
#[Storage('s3')] Filesystem $files,
#[Config('app.timezone')] string $timezone,
) {}
}
Metaprogramming Thorns
Good Metaprogramming like in Laravel
Learn the contract, and the framework becomes simpler
X: @wendell_adriel
Website: wendelladriel.com