2016年10月31日 星期一

Voyager – A Laravel Admin Package

Voyager is a new package created by The Control Group that provides a complete admin system to quickly scaffold out your app. It features:
Media Manager
Voyager has an amazing fully function media manager which allows you to view/edit/delete files from your storage. All files in your application will be easily accessible and will live in a single place. Compatible with local or s3 file storage.
Menu Builder
You can easily build as many menus for your site. You can add/edit/delete menu items from as many menus as you would like. Then it’s super easy to display your menu on the front-end of your app:
Menu::display('main')
Database Manager
You can actually manipulate your database directly from the Voyager admin. You can add, edit, or delete tables. When creating a new table you can also specify if you would like voyager to create your Model for you.
BREAD/CRUD Builder
Similar to CRUD, Voyager has a system called BREAD which is Browse, Read, Edit, Add, and Delete. You can easily add any BREAD views and functionality to any table in your database. Have a products table, easily add the Browse Read Edit Add & Delete functionality in seconds!
Demo Video
























7:57 / 7:57

發生錯誤。

請前往 www.youtube.com 觀看這部影片,或在瀏覽器中啟用 JavaScript (如果尚未啟用)。

For more information on Voyager check out the official site and it’s documentation

from : https://laravel-news.com/2016/10/voyager/

大批量假数据填充的正确方法

开发 数据填充 时,必须 特别注意 php artisan db:seed 的运行效率,否则随着项目的代码量越来越大,db:seed 的运行时间会变得越来越长,有些项目多达几分钟甚至几十分钟。
只有当 db:seed 运行起来很快的时候,才能完全利用数据填充工具带来的便利,而不是最后变成累赘。

模型工厂#

Laravel 的官方文档中,建议 使用模型工厂来填充数据 ,在日常使用中,需要注意以下。

避免使用 create 方法#

在使用 模型工厂函数 来书写假数据插入逻辑时,要注意避免使用 create 方法,因为每一次就是一条 SQL 语句。
factory(\App\Models\User::class)->times(300)->create();
以下截图是一个使用 factory 辅助函数的例子,插入 300 条数据,总共执行了 602 条 SQL 语句,总执行时长为 23.91 秒。
file
轻轻松松运行时间就累积起来了,你能想象运行一次 db:seed 要半个小时是什么感觉么?
c4o3E6gq7W.png

正确的做法:使用 make 方法#

$users = factory(\App\Models\User::class)->times(1000)->make();
\App\Models\User::insert($users->toArray());
file
感谢 @NauxLiu :smile: :sparkles: :sparkles:

传统方式#

一个错误的例子#

下面代码执行了 1000 条 SQL 语句,在书写数据填充的时候,也是要尽量避免。
$faker = Faker::create();
$users = User::lists('id');

foreach (range(1, 1000) as $index)
{
    Topic::create([
        'user_id'     => $faker->randomElement($users),
        'title'       => $faker->sentence(),
        'description' => $faker->text(),
    ]);
}

解决方案#

使用 DB:insert,直接,快速,一步到位:
$faker = Faker::create();
$users = User::lists('id');
$datas = [];

foreach (range(1, 1000) as $index)
{
  $datas[] = [
      'user_id'     => $faker->randomElement($users),
      'title'       => $faker->sentence(),
      'description' => $faker->text(),
      'created_at'  => Carbon::now()->toDateTimeString(),
      'updated_at'  => Carbon::now()->toDateTimeString(),
  ];
}
DB::table('topics')->insert($datas);
只有 db:seed 运行起来很快的时候,你才可以随时随地,想 seed 就 seed。

from : https://laravel-china.org/topics/2066

「记录」使用 Laravel elixir、gulp、gulp-Sass 遇到的问题和解决方案

前些天升级了 Homestead 到指定版本(见 这里),发现好几个项目的 elixir、gulp、gulp-sass 随机搭配着出问题。
如:
$ gulp
[07:12:37] Warning: gulp version mismatch:
[07:12:37] Global gulp is 3.9.0
[07:12:37] Local gulp is 3.8.11
[07:12:38] Using gulpfile ~/Projects/phphub.org/laravel-china/gulpfile.js
[07:12:38] Starting 'default'...
[07:12:38] Starting 'sass'...
[07:12:38] 'sass' errored after 14 ms
[07:12:38] Error: `libsass` bindings not found. Try reinstalling `node-sass`?
    at getBinding (/Users/charliejade/Projects/phphub.org/laravel-china/node_modules/laravel-elixir/node_modules/gulp-sass/node_modules/node-sass/lib/index.js:22:11)
    at Object. (/Users/charliejade/Projects/phphub.org/laravel-china/node_modules/laravel-elixir/node_modules/gulp-sass/node_modules/node-sass/lib/index.js:188:23)
    at Module._compile (module.js:425:26)
    at Object.Module._extensions..js (module.js:432:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object. (/Users/charliejade/Projects/phphub.org/laravel-china/node_modules/laravel-elixir/node_modules/gulp-sass/index.js:3:17)
    at Module._compile (module.js:425:26)
Error running task sequence: { task: 'sass',
  message: 'sass catch',
  duration: 0.014146409,
  hrDuration: [ 0, 14146409 ],
  err: [Error: `libsass` bindings not found. Try reinstalling `node-sass`?] }
[07:12:38] Finished 'default' after 19 ms
跟目录使用下面命令升级本地 gulp :
$ npm install gulp@3.9.0 --save
又出现:
Error: Cannot find module 'orchestrator'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object. (/Users/heikki/node_modules/gulp/index.js:4:20)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
。。。

解决方法#

修改 package.json 文件:
{
  "devDependencies": {
    "gulp": "*",
    "gulp-sass": "*",
    "laravel-elixir": "*"
  }
}
意指所有依赖都使用最新版本,最后安装成功。

from : https://laravel-china.org/topics/2101

Laravel 下使用 Guzzle 编写多线程爬虫实战

Guzzle 库是一套强大的 PHP HTTP 请求套件。
本文重点演示如何使用 Guzzle 发起多线程请求。

参考#

创建命令#

1. 运行命令行创建命令#

php artisan make:console MultithreadingRequest --command=test:multithreading-request

2. 注册命令#

编辑 app/Console/Kernel.php,在 $commands 数组中增加:
Commands\MultithreadingRequest::class,

3. 测试下命令#

修改 app/Console/Commands/MultithreadingRequest.php 文件,在 handle 方法中增加:
$this->info('hello');
输出:
$ php artisan test:multithreading-request
hello

4. 安装 Guzzle#

composer require guzzlehttp/guzzle "6.2"

直接贴代码#

一份可运行的代码胜过千言万语呀。
下面代码是 app/Console/Commands/MultithreadingRequest.php 里的内容:
 namespace App\Console\Commands;

use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;

class MultithreadingRequest extends Command
{
    private $totalPageCount;
    private $counter        = 1;
    private $concurrency    = 7;  // 同时并发抓取

    private $users = ['CycloneAxe', 'appleboy', 'Aufree', 'lifesign',
                        'overtrue', 'zhengjinghua', 'NauxLiu'];

    protected $signature = 'test:multithreading-request';
    protected $description = 'Command description';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $this->totalPageCount = count($this->users);

        $client = new Client();

        $requests = function ($total) use ($client) {
            foreach ($this->users as $key => $user) {

                $uri = 'https://api.github.com/users/' . $user;
                yield function() use ($client, $uri) {
                    return $client->getAsync($uri);
                };
            }
        };

        $pool = new Pool($client, $requests($this->totalPageCount), [
            'concurrency' => $this->concurrency,
            'fulfilled'   => function ($response, $index){

                $res = json_decode($response->getBody()->getContents());

                $this->info("请求第 $index 个请求,用户 " . $this->users[$index] . " 的 Github ID 为:" .$res->id);

                $this->countedAndCheckEnded();
            },
            'rejected' => function ($reason, $index){
                $this->error("rejected" );
                $this->error("rejected reason: " . $reason );
                $this->countedAndCheckEnded();
            },
        ]);

        // 开始发送请求
        $promise = $pool->promise();
        $promise->wait();
    }

    public function countedAndCheckEnded()
    {
        if ($this->counter < $this->totalPageCount){
            $this->counter++;
            return;
        }
        $this->info("请求结束!");
    }
}
运行结果:
$ php artisan test:multithreading-request
请求第 5 个请求,用户 zhengjinghua 的 Github ID 为:3413430
请求第 6 个请求,用户 NauxLiu 的 Github ID 为:9570112
请求第 0 个请求,用户 CycloneAxe 的 Github ID 为:6268176
请求第 1 个请求,用户 appleboy 的 Github ID 为:21979
请求第 2 个请求,用户 Aufree 的 Github ID 为:5310542
请求第 3 个请求,用户 lifesign 的 Github ID 为:2189610
请求第 4 个请求,用户 overtrue 的 Github ID 为:1472352
请求结束!
注意请求是同时发送过去的,因为 concurrency 并发设置了 7,所以 7 个请求同时发送,只不过接收到返回的时间点不一样。

from : https://laravel-china.org/topics/2130

wibiya widget