安裝admin
laravel new admin
-
composer require --dev barryvdh/laravel-ide-helper php artisan ide-helper:generate #php artisan ide:models//要在容器裡面執行
建立Dockerfile
FROM php:7.4 RUN sed -i s/deb.debian.org/mirrors.aliyun.com/g /etc/apt/sources.list RUN apt-get update && apt-get install -y \ libfreetype6-dev \ # libjpeng62-turbo-dev \ libmcrypt-dev \ libpng-dev \ zlib1g-dev \ libxml2-dev \ libzip-dev \ libonig-dev \ graphviz \ && docker-php-ext-configure gd \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql \ && docker-php-ext-install mysqli \ && docker-php-ext-install zip \ && docker-php-ext-install sockets \ # && docker-php-ext-source delete \ #docker-php-source delete:在當前目錄下---刪除 /usr/src/php 目錄 && curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/local/bin --filename=composer WORKDIR /app COPY . . RUN composer install CMD php artisan serve --host=0.0.0.0 EXPOSE 8000
建立docker-compose.yaml
version: '3.8' services: admin: build: context: . dockerfile: Dockerfile command: 'php artisan serve --host=0.0.0.0' volumes: - .:/app ports: - 8000:8000 depends_on: - admin_db admin_queue: build: context: . dockerfile: Dockerfile command: 'php artisan queue:work' depends_on: - admin_db admin_db: image: mysql:5.7.22 environment: MYSQL_DATABASE: root MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_ROOT_PASSWORD: root volumes: - ./storage/dbdata:/var/lib/mysql ports: - 3307:3306
.env
DB_CONNECTION=mysql DB_HOST=admin_db DB_PORT=3306 DB_DATABASE=root DB_USERNAME=root DB_PASSWORD=root QUEUE_CONNECTION=rabbitmq RABBITMQ_HOST=shark.rmq.cloudamqp.com RABBITMQ_PORT=5672 RABBITMQ_USER=xxx RABBITMQ_PASSWORD=xxxx-ruw1 RABBITMQ_VHOST=xxxx RABBITMQ_QUEUE=admin_queue
- 檢驗啟動 `docker-compose up`
- `php artisan make:migration create_products_table`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('image');
$table->unsignedBigInteger('likes')->default(0);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('products');
}
}
- 進入容器
docker-compose exec admin sh
- php artisan make:migrate
- php artisan make:factory ProductFactory
- php artisan make:model Product
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductFactory extends Factory
{
public function definition()
{
return [
'title' => $this->faker->text(30),
'image' => $this->faker->imageUrl(),
//
];
}
}
- php artisan make:seeder ProductSeeder
- php artisan make:seeder UserSeeder
#DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// \App\Models\User::factory(10)->create();
$this->call([
UserSeeder::class,
ProductSeeder::class,
]);
}
}
#ProductSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Product;
use Illuminate\Database\Seeder;
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Product::factory(20)->create();
}
}
#UserSeeder.php
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::factory(20)->create();
}
}
php artisan db:seed
php artisan make:controller ProductController
<?php
namespace App\Http\Controllers;
use App\Jobs\ProductCreated;
use App\Jobs\ProductDeleted;
use App\Jobs\ProductUpdated;
use App\Models\Product;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ProductController extends Controller
{
public function index()
{
return Product::all();
}
public function show($id)
{
return Product::find($id);
}
public function store(Request $request)
{
$product = Product::create($request->only('title','image'));
ProductCreated::dispatch($product->toArray())->onQueue('main_queue');
return response($product, Response::HTTP_CREATED);
}
public function update($id, Request $request)
{
$product = Product::find($id);
$product->update($request->only('title','image'));
ProductUpdated::dispatch($product->toArray())->onQueue('main_queue');
return response($product, Response::HTTP_ACCEPTED);
}
public function destroy($id)
{
Product::destroy($id);
ProductDeleted::dispatch($id)->onQueue('main_queue');
return response(null, Response::HTTP_NO_CONTENT);
}
}
- api.php
Route::apiResource('products', ProductController::class);
- 建立HTTP Request
GET http://xxxxx:8000/api/products Accept: application/json
- php artisan route:list
安裝main
laravel new main
php artisan ide-helper:generate
建立Dockerfile
FROM php:7.4 RUN sed -i s/deb.debian.org/mirrors.aliyun.com/g /etc/apt/sources.list RUN apt-get update && apt-get install -y \ libfreetype6-dev \ # libjpeng62-turbo-dev \ libmcrypt-dev \ libpng-dev \ zlib1g-dev \ libxml2-dev \ libzip-dev \ libonig-dev \ graphviz \ && docker-php-ext-configure gd \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql \ && docker-php-ext-install mysqli \ && docker-php-ext-install zip \ && docker-php-ext-install sockets \ # && docker-php-ext-source delete \ #docker-php-source delete:在當前目錄下---刪除 /usr/src/php 目錄 && curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/local/bin --filename=composer WORKDIR /app COPY . . RUN composer install
建立docker-compose.yaml
version: '3.8' services: main: build: context: . dockerfile: Dockerfile command: 'php artisan serve --host=0.0.0.0' volumes: - .:/app ports: - 8001:8000 depends_on: - main_db main_queue: build: context: . dockerfile: Dockerfile command: 'php artisan queue:work' depends_on: - main_db main_db: image: mysql:5.7.22 environment: MYSQL_DATABASE: main MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_ROOT_PASSWORD: root volumes: - ./storage/dbdata:/var/lib/mysql ports: - 3308:3306
.env
DB_CONNECTION=mysql DB_HOST=main_db DB_PORT=3306 DB_DATABASE=main DB_USERNAME=root DB_PASSWORD=root QUEUE_CONNECTION=rabbitmq RABBITMQ_HOST=shark.rmq.cloudamqp.com RABBITMQ_PORT=5672 RABBITMQ_USER=uiuzjuuc RABBITMQ_PASSWORD=xxxxxxxxxx RABBITMQ_VHOST=xxxx RABBITMQ_QUEUE=main_queue
檢驗啟動
docker-compose up
進入容器
docker-compose exec main sh
php artisan make:migration create_products_table
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateProductsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('products', function (Blueprint $table) { $table->unsignedBigInteger('id')->primary(); $table->string('title'); $table->string('image'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('products'); } }
php artisan make:migrate
php artisan make:controller ProductController
<?php namespace App\Http\Controllers; use App\Jobs\ProductLiked; use App\Models\Product; use App\Models\ProductUser; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class ProductController extends Controller { public function index() { return Product::all(); } public function like($id, Request $request) { // $response = \Http::get('http://docker.for.mac.localhost:8000/api/user'); $response = \Http::get('http://47.113.xxx:8000/api/user'); $user = $response->json(); try { $productUser = ProductUser::create([ 'user_id' => $user['id'], 'product_id' => $id, ]); ProductLiked::dispatch($productUser->toArray())->onQueue('admin_queue'); return response([ 'message' => 'success', ]); } catch (\Exception $exception) { return response([ 'error' => 'you already liked this product!11111111', 'error1' => $exception->getMessage(), ],Response::HTTP_BAD_REQUEST); } return $response->json(); } }
php artisan make:model Product
api.php
Route::get('products',[ProductController::class,'index']); Route::post('products/{id}/like',[ProductController::class,'like']);
-
# https://github.com/vyuldashev/laravel-queue-rabbitmq composer require vladimir-yuldashev/laravel-queue-rabbitmq
queue.php
'rabbitmq' => [ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), 'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class, 'hosts' => [ [ 'host' => env('RABBITMQ_HOST', '127.0.0.1'), 'port' => env('RABBITMQ_PORT', 5672), 'user' => env('RABBITMQ_USER', 'guest'), 'password' => env('RABBITMQ_PASSWORD', 'guest'), 'vhost' => env('RABBITMQ_VHOST', '/'), ], ], 'options' => [ 'ssl_options' => [ 'cafile' => env('RABBITMQ_SSL_CAFILE', null), 'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null), 'local_key' => env('RABBITMQ_SSL_LOCALKEY', null), 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), ], 'queue' => [ 'job' => VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class, ], ], /* * Set to "horizon" if you wish to use Laravel Horizon. */ 'worker' => env('RABBITMQ_WORKER', 'default'), ],
php artisan command FireEvent
<?php namespace App\Console\Commands; use App\Jobs\TestJob; use Illuminate\Console\Command; class FireEvent extends Command { protected $signature = 'fire'; public function handle() { TestJob::dispatch(); } }
php artisan make:job TestJob
<?php
namespace App\Providers;
use App\Jobs\ProductCreated;
use App\Jobs\ProductDeleted;
use App\Jobs\ProductUpdated;
use App\Jobs\TestJob;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
public function boot()
{
// //7.4寫法
// \App::bindMethod(TestJob::class . '@handle', fn($job) => $job->handle());
// 舊版本
// \App::bindMethod(TestJob::class . '@handle', function ($job){
// return $job->handle();
// });
\App::bindMethod(ProductCreated::class . '@handle', fn($job) => $job->handle());
\App::bindMethod(ProductUpdated::class . '@handle', fn($job) => $job->handle());
\App::bindMethod(ProductDeleted::class . '@handle', fn($job) => $job->handle());
}
}
docker-compose exec main sh
php artisan queue:work
admin 執行php artisan make:job ProductCreated
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductCreated implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; /** * Create a new job instance. * * @return void */ public function __construct($data) { $this->data = $data; } /** * Execute the job. * * @return void */ public function handle() { // } }
# ProductUpdated.php <?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductUpdated implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; /** * Create a new job instance. * * @return void */ public function __construct($data) { $this->data = $data; } /** * Execute the job. * * @return void */ public function handle() { // } }
#ProductLiked.php <?php namespace App\Jobs; use App\Models\Product; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductLiked implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; public function __construct($data) { $this->data = $data; } public function handle() { $product = Product::find($this->data['product_id']); $product->likes++; $product->save(); } }
#ProductDeleted.php <?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductDeleted implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $id; /** * Create a new job instance. * * @return void */ public function __construct($id) { $this->id = $id; } /** * Execute the job. * * @return void */ public function handle() { // } }
<?php namespace App\Providers; use App\Jobs\ProductLiked; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { public function boot() { \App::bindMethod(ProductLiked::class . '@handle', fn($job) => $job->handle()); } }
main 執行php artisan make:job ProductCreated
<?php namespace App\Jobs; use App\Models\Product; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductCreated implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; public function __construct($data) { $this->data = $data; } public function handle() { Product::create([ 'id' => $this->data['id'], 'title' => $this->data['title'], 'image' => $this->data['image'], 'created_at' => $this->data['created_at'], 'updated_at' => $this->data['updated_at'], ]); } }
#ProductDeleted.php <?php namespace App\Jobs; use App\Models\Product; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductDeleted implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $id; /** * Create a new job instance. * * @return void */ public function __construct($id) { $this->id = $id; } /** * Execute the job. * * @return void */ public function handle() { Product::destroy($this->id); } }
#ProductLiked.php <?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductLiked implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; public function __construct($data) { $this->data = $data; } public function handle() { } }
#ProductUpdated.php <?php namespace App\Jobs; use App\Models\Product; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProductUpdated implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $data; /** * Create a new job instance. * * @return void */ public function __construct($data) { $this->data = $data; } /** * Execute the job. * * @return void */ public function handle() { // $product = Product::find($this->data['id']); $product->update([ 'title' => $this->data['data'], 'image' => $this->data['image'], 'created_at' => $this->data['created_at'], 'updated_at' => $this->data['updated_at'], ]); } }
本作品採用《CC 協議》,轉載必須註明作者和本文連結