Hello, Habr. Recently I got an interesting project in my hands, which, despite its simplicity, demanded not to use any framework. There was no talk of packages, so it was decided to use the usual Laravel components. If you need to use queues, Eloquent or a container - welcome to cat.
On the simplicity of dividing the framework into components
Starting with Laravel 4, all components are separate packages, which in theory can be made to work in any PHP project. However, some components require additional customization, which in the main framework is hidden under the hood.
Components
Container
Of all the components under consideration, illuminate/container
is the easiest to install and use.
<?php use Illuminate\Container\Container; $container = Container::getInstance(); return $container->make(Foo::class);
However, calling a static method on the Container
class every time you use a container is not a good idea. The app()
is available in the framework, which will return the global container instance to us, however, we need to create one manually.
Create a helpers.php
file for such helpers, and add it to startup.
"autoload": { "files": [ "src/helpers.php" ], "psr-4": { "YourApp\\": "src/" } }
Add the app()
helper to the file.
<?php use Illuminate\Container\Container; if (! function_exists('app')) { function app($abstract = null, array $parameters = []) { if (is_null($abstract)) { return Container::getInstance(); } return Container::getInstance()->make($abstract, $parameters); } }
Done. You can try to use a helper.
<?php return app(Foo::class);
Query Builder and Eloquent
To use the illuminate/database
component, we will use Capsule\Manager
, a class designed to work with the query builder outside of Laravel.
Let's start by setting up a connection to the database. It is advisable to carry out this configuration at the startup stage of your application, immediately after connecting 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' => '', ]);
You can get started with the query builder.
<?php use Illuminate\Database\Capsule\Manager; return Manager::table('orders')->get();
What about Eloquent?
<?php namespace YourApp\Models; use Illuminate\Database\Eloquent\Model; class Order extends Model { protected $fillable = [ 'name', ]; }
<?php use YourApp\Models\Order; Order::first();
The situation is more complicated with migrations - on the one hand, there is a Schema Builder in the kit. On the other hand, there is no automatic mechanism for starting migrations.
<?php use Illuminate\Database\Capsule\Manager; Manager::schema()->create('orders', function ($table) { $table->bigIncrements('id'); $table->string('name'); $table->timestamps(); });
To start, just execute the file with migration: php migration.php
Queues
Queues also have their own Capsule
, however, the analogs of queue:work
and queue:listen
must be written manually.
Let's start with the Application
class. In Laravel, this class is used as a global container instance, which, in addition to the Illuminate\Container\Container
methods, contains auxiliary methods for working with the framework (current version, storage paths, resources). However, our class will contain only one method - isDownForMaintenance
. It is necessary for the work of the worker, as it determines the state of the application at the moment.
<?php namespace YourApp; use Illuminate\Container\Container; class Application extends Container { public function isDownForMaintenance() { return false; } }
Next, we need to register the illuminate/events
provider, and bind the Illuminate\Contracts\Events\Dispatcher
contract to the events
alias.
<?php use YourApp\Application; use Illuminate\Contracts\Events\Dispatcher; $application = Application::getInstance(); $application->bind(Dispatcher::class, 'events');
Now you need to create the Capsule
instance, and add the connection configurations there.
Example configuration for the database
<?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');
Configuration example for Redis (requires 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();
The final step in the configuration is to add an analog Exception Handler .
<?php use Illuminate\Contracts\Debug\ExceptionHandler; class Handler implements ExceptionHandler { public function report(Exception $e) {
Queue configuration completed. Now you can start writing 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);
Now to start the queue worker, just write php worker.php
.
If there is a need to use queue:listen
, then you need to create two separate files. One is a daemon that listens to the queue and runs a second file on every new job. The second file, in turn, acts as the executor of the task.
worker.php
<?php require_once __DIR__.'/bootstrap/bootstrap.php'; use Illuminate\Queue\Listener; use Illuminate\Queue\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);
We pass to use. All methods can be viewed in the API.
<?php use Illuminate\Queue\Capsule\Manager; Manager::push(SomeJob::class);