Divisez Laravel en composants

Salut, Habr. Récemment, j'ai eu entre les mains un projet intéressant qui, malgré sa simplicité, exigeait de ne pas utiliser de framework. Il n'a pas été question de packages, il a donc été décidé d'utiliser les composants Laravel habituels. Si vous devez utiliser des files d'attente, Eloquent ou un conteneur - bienvenue chez cat.


Sur la simplicité de la division du cadre en composants


À partir de Laravel 4, tous les composants sont des packages séparés, qui peuvent en théorie fonctionner dans n'importe quel projet PHP. Cependant, certains composants nécessitent une personnalisation supplémentaire, qui dans le cadre principal est caché sous le capot.


Composants


Conteneur


De tous les composants à l'étude, l' illuminate/container est le plus facile à installer et à utiliser.


 <?php use Illuminate\Container\Container; $container = Container::getInstance(); return $container->make(Foo::class); 

Cependant, appeler une méthode statique sur la classe Container chaque fois que vous utilisez un conteneur n'est pas une bonne idée. L' app() est disponible dans le cadre, qui nous renverra l'instance de conteneur global, cependant, nous devons en créer une manuellement.


Créez un fichier helpers.php pour ces assistants et ajoutez-le au démarrage.


 "autoload": { "files": [ "src/helpers.php" ], "psr-4": { "YourApp\\": "src/" } } 

Ajoutez l'assistant app() au fichier.


 <?php use Illuminate\Container\Container; if (! function_exists('app')) { /** * Get the available container instance. * * @param string|null $abstract * @param array $parameters * @return mixed|\Illuminate\Container\Container */ function app($abstract = null, array $parameters = []) { if (is_null($abstract)) { return Container::getInstance(); } return Container::getInstance()->make($abstract, $parameters); } } 

C'est fait. Vous pouvez essayer d'utiliser un assistant.


 <?php return app(Foo::class); 

Générateur de requêtes et éloquent


Pour utiliser le composant illuminate/database , nous utiliserons Capsule\Manager , une classe conçue pour fonctionner avec le générateur de requêtes en dehors de Laravel.


Commençons par configurer une connexion à la base de données. Il est conseillé d'effectuer cette configuration au stade de démarrage de votre application, immédiatement après avoir connecté autoload.php .


 <?php require_once __DIR__.'/../vendor/autoload.php'; use Illuminate\Database\Capsule\Manager; $manager = new Manager; $manager->addConnection([ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'database', 'username' => 'root', 'password' => 'password', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ]); //        Capsule. $manager->setAsGlobal(); 

Vous pouvez commencer avec le générateur de requêtes.


 <?php use Illuminate\Database\Capsule\Manager; return Manager::table('orders')->get(); 

Et Eloquent?


 <?php namespace YourApp\Models; use Illuminate\Database\Eloquent\Model; class Order extends Model { protected $fillable = [ 'name', ]; } 

 <?php use YourApp\Models\Order; Order::first(); 

La situation est plus compliquée avec les migrations - d'une part, il y a un générateur de schéma dans le kit. En revanche, il n'y a pas de mécanisme automatique pour démarrer les migrations.


 <?php use Illuminate\Database\Capsule\Manager; Manager::schema()->create('orders', function ($table) { $table->bigIncrements('id'); $table->string('name'); $table->timestamps(); }); 

Pour commencer, il suffit d'exécuter le fichier avec migration: php migration.php


Files d'attente


Les files d'attente ont également leur propre Capsule , cependant, les analogues de queue:work d' queue:work et queue:listen doivent être écrits manuellement.


Commençons par la classe Application . Dans Laravel, cette classe est utilisée comme une instance de conteneur globale qui, en plus des méthodes Illuminate\Container\Container , contient des méthodes auxiliaires pour travailler avec le framework (version actuelle, chemins de stockage, ressources). Cependant, notre classe ne contiendra qu'une seule méthode - isDownForMaintenance . Il est nécessaire pour le travail du travailleur, car il détermine l'état de l'application en ce moment.


 <?php namespace YourApp; use Illuminate\Container\Container; class Application extends Container { public function isDownForMaintenance() { return false; } } 

Ensuite, nous devons enregistrer le fournisseur illuminate/events et lier le Illuminate\Contracts\Events\Dispatcher à l'alias d' events .


 <?php use YourApp\Application; use Illuminate\Contracts\Events\Dispatcher; $application = Application::getInstance(); $application->bind(Dispatcher::class, 'events'); 

Vous devez maintenant créer l'instance Capsule et y ajouter les configurations de connexion.


Exemple de configuration pour la base de données


 <?php use YourApp\Application; use Illuminate\Queue\Capsule\Manager; use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\ConnectionResolver; $container = Application::getInstance(); $queue = new Manager($container); $queue->addConnection([ 'driver' => 'database', 'table' => 'jobs', 'connection' => 'default', 'queue' => 'default', ], 'default'); // ,    Illuminate\Database\Capsule\Manager       $queue->setAsGlobal(); $connection = Capsule::schema()->getConnection(); $resolver = new ConnectionResolver(['default' => $connection]); $queue->getQueueManager()->addConnector('database', function () use ($resolver) { return new DatabaseConnector($resolver); }); 

Exemple de configuration pour Redis (nécessite illuminate/redis )


 <?php use Illuminate\Redis\RedisManager; use Illuminate\Queue\Capsule\Manager; $container->bind('redis', function () use ($container) { return new RedisManager($container, 'predis', [ 'default' => [ 'host' => '127.0.0.1', 'password' => null, 'port' => 6379, 'database' => 0, ] ]); }); $queue = new Manager($container); $queue->addConnection([ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', ], 'default'); $queue->setAsGlobal(); 

La dernière étape de la configuration consiste à ajouter un gestionnaire d'exceptions analogique.


 <?php use Illuminate\Contracts\Debug\ExceptionHandler; class Handler implements ExceptionHandler { public function report(Exception $e) { // ,  Exception     . // :   Sentry,    . } public function render($request, Exception $e) { //   } public function renderForConsole($output, Exception $e) { //  ,     -  } public function shouldReport(\Exception $e) { //      } } app()->bind('exception.handler', function () { return new Handler; }); 

La configuration de la file d'attente est terminée. Vous pouvez maintenant commencer à écrire la queue:work .


 <?php require_once __DIR__.'/bootstrap/bootstrap.php'; use Illuminate\Queue\Worker; use Illuminate\Queue\Capsule\Manager; use Illuminate\Queue\WorkerOptions; $queueManager = Manager::getQueueManager(); $worker = new Worker($queueManager, app('events'), app('exception.handler')); $worker->daemon('default', 'default', new WorkerOptions); 

Maintenant, pour démarrer un travailleur de file d'attente, écrivez simplement php worker.php .


S'il est nécessaire d'utiliser la queue:listen , vous devez créer deux fichiers distincts. L'un est un démon qui écoute la file d'attente et exécute un deuxième fichier à chaque nouvelle tâche. Le deuxième fichier, à son tour, sert d'exécuteur testamentaire.


travailleur.php


 <?php require_once __DIR__.'/bootstrap/bootstrap.php'; use Illuminate\Queue\Listener; use Illuminate\Queue\ListenerOptions; //  ,   " ",  Laravel  artisan,        work.php. // https://github.com/laravel/framework/blob/6.x/src/Illuminate/Queue/Listener.php#L72 define('ARTISAN_BINARY', 'work.php'); $worker = app(Listener::class, ['commandPath' => __DIR__]); $worker->setOutputHandler(function ($type, $line) { echo $line; }); $worker->listen('default', 'default', new ListenerOptions); 

work.php


 <?php require_once 'bootstrap/bootstrap.php'; use Illuminate\Queue\Worker; use Illuminate\Queue\WorkerOptions; use Illuminate\Queue\Capsule\Manager; $queueManager = Manager::getQueueManager(); $worker = new Worker($queueManager, app('events'), app('exception.handler')); $worker->runNextJob('default', 'default', new WorkerOptions); 

Nous passons à utiliser. Toutes les méthodes peuvent être consultées dans l' API.


 <?php use Illuminate\Queue\Capsule\Manager; Manager::push(SomeJob::class); 

Source: https://habr.com/ru/post/fr475144/


All Articles