memio/model
Memio Model provides PHP objects to describe code structures (classes, interfaces, methods, properties, parameters, types and namespaces). Use it to build an in-memory representation of PHP code for analysis, tooling, or code generation workflows.
Installation:
composer require memio/model
Ensure memio/model is listed in composer.json under require.
Basic Usage: Start by describing a simple model class:
use Memio\Model\Describer;
$describer = new Describer();
$model = $describer->describe([
'name' => 'User',
'properties' => [
'id' => ['type' => 'int', 'primary' => true],
'name' => ['type' => 'string', 'maxLength' => 255],
'email' => ['type' => 'string', 'unique' => true],
'created_at' => ['type' => 'datetime'],
],
]);
This generates a User model class dynamically with the specified properties.
First Use Case:
Use memio/model to scaffold a Laravel Eloquent model without writing boilerplate:
$model = $describer->describe([...])->generate();
$model->save(['name' => 'John Doe', 'email' => 'john@example.com']);
tests/ directory in the package for real-world usage patterns.Describer, Generator, and Model classes in the Memio\Model namespace.Scaffolding Models:
Use Describer to generate models from database schemas or API contracts:
$schema = DB::select('SHOW COLUMNS FROM users');
$describer->describeFromSchema($schema)->generate();
Integration with Laravel:
Override Laravel’s model generation by hooking into booted events:
Model::booted(function () {
$describer = new Describer();
$describer->describe([...])->generate();
});
Define Relationships:
$describer->describe([
'name' => 'Post',
'properties' => [...],
'relationships' => [
'author' => ['type' => 'belongsTo', 'model' => 'User'],
'comments' => ['type' => 'hasMany', 'model' => 'Comment'],
],
]);
Add Events:
$describer->describe([
'name' => 'Order',
'events' => [
'creating' => 'validateStock',
'saved' => 'sendNotification',
],
]);
Use memio/model to validate incoming requests:
use Memio\Model\Validator;
$validator = new Validator();
$input = $request->all();
$errors = $validator->validate($input, $describer->describe([...]));
Caching Generated Models: Memio generates classes at runtime. Cache the output to avoid regeneration:
$generatedClass = $describer->describe([...])->generate();
file_put_contents(app_path("Models/Generated/{$generatedClass->getName()}.php"), $generatedClass->getCode());
Namespace Conflicts: Ensure generated model namespaces match your Laravel app’s structure:
$describer->setNamespace('App\Models');
Type System Limitations:
Memio’s type system is PHP 8.0+ focused. For older PHP, use string as a fallback.
Database Sync Issues:
If the DB schema changes, regenerate models to avoid ColumnNotFoundException.
dd($describer->describe([...])->getModel()) to inspect the generated structure.$code = $describer->describe([...])->generate()->getCode();
file_put_contents('debug_model.php', $code);
$describer->setStrict(true); // Throws exceptions for invalid descriptions.
Custom Generators:
Extend Memio\Model\Generator to add Laravel-specific traits:
class LaravelGenerator extends Generator {
public function generate(): Model {
$model = parent::generate();
$model->addTrait('Illuminate\Database\Eloquent\Concerns\HasUuids::class');
return $model;
}
}
Plugin System:
Use Describer::addPlugin() to inject custom logic (e.g., soft deletes):
$describer->addPlugin(function ($description) {
$description['properties']['deleted_at'] = ['type' => 'datetime', 'nullable' => true];
});
Event Hooks:
Override Model::fireModelEvent() to integrate with Laravel’s event system:
$model->on('saving', function ($model) {
$model->updated_at = now();
});
composer.json:
"autoload": {
"psr-4": {
"App\\Models\\Generated\\": "app/Models/Generated/"
}
}
if (app()->environment('production')) {
$describer->disableRegeneration();
}
How can I help you explore Laravel packages today?