@42withyou
2016-09-23T07:25:18.000000Z
字数 8221
阅读 596
未分类
public function __construct(){$this->users = new UserRepository;}public function __construct(UserRepository $users){$this->users = $users;}
注册一个实例到容器中
$this->app['context'] = $this->app->share(function ($app) {return new Context;});
或者绑定一个 Interface 到一个实体(Entity)
$this->app->bind(\App\Repositories\Api\UserRepositoryInterface::class,\App\Repositories\Api\Eloquent\UserRepository::class);
参考 灵析 api
不过类似 context 这种需求,在整个应用生命周期只需要一个,所以
$this->app->singleton('context', function () {return $this->app->make(\App\Utilities\Context\Context::class);});
关于 Conainer 的实现, 有 laravel 的实现方式 Illuminate\Container,基本上出了 Thinkphp 所有国外框架都有容器这么一个概念。
参考 Demo
<?phpuse Context;class HomeController{public function index(){Context::all();}}
<?phpclass ContextFacade extends Facade{protected static function getFacadeAccessor(){return 'context';}}
<?phpabstract class Facade{protected static function getFacadeAccessor(){throw new RuntimeException('Facade does not implement getFacadeAccessor method.');}public static function __callStatic($method, $args){// 返回容器中绑定的对象$instance = static::getFacadeRoot();if (! $instance) {throw new RuntimeException('A facade root has not been set.');}// ...$args ???return $instance->$method(...$args);}}
关于解构符(spread operator)
function foo($a, ...$args){$a // 1,$args // [2,3,4]}foo(...[1,2,3,4]);
先看个例子感受一波
return collect($users)->filter(function ($user) {return $user->isActive();})// ->reject(function ($user) { return $user->notActive() })->map(function ($user) {return $user->posts;})->reduce(function ($total, $item) {return $total + $item->commentCount;}, 0);// ->sum('commentCount');
$people = collect([['name' => 'RryLee', 'single' => true, 'email' => 'RryLee@justering.com'],['name' => 'Yekz', 'single' => true, 'email' => 'Yekz@justering.com'],['name' => 'Ferman', 'single' => false, 'email' => 'Ferman@justering.com'],['name' => 'Sky', 'single' => true, 'email' => 'Sky@justering.com'],['name' => 'Casper', 'single' => false, 'email' => 'Casper@justering.com'],]);$emails = [];foreach ($people as $person) {if ($person['single']) {$emails[] = $person['email'];}}// collection.$people->filter(function ($person) {return $person->single;})->pluck('email');
$people = collect([['name' => 'RryLee','email' => 'RryLee@justering.com','projects' => [['name' => 'api', 'code_line' => 7444],['name' => 'cfnew', 'code_line' => 5020],['name' => 'lingxi', 'code_line' => 1200],],],['name' => 'Yekz','email' => 'Yekz@justering.com','projects' => [['name' => 'api', 'code_line' => 120],['name' => 'cfnew', 'code_line' => 4000],['name' => 'lingxi', 'code_line' => 8000],['name' => 'mail', 'code_line' => 2122],['name' => 'pay', 'code_line' => 1201],],],['name' => 'Ferman','email' => 'Ferman@justering.com','projects' => [['name' => 'cfnew', 'code_line' => 3000],['name' => 'lingxi', 'code_line' => 5000],['name' => 'pay', 'code_line' => 7000],],],]);$people->pluck('projects')/*** [* [['name' => 'api', 'code_line' => 7444],['name' => 'cfnew', 'code_line' => 5020],['name' => 'lingxi', 'code_line' => 1200],* ],* [...],* [...],* ]*/->flatten(1)/*** [* ['name' => 'api', 'code_line' => 7444],* ['name' => ...],* ['name' => ...],* ]*/->groupBy('name')/*** [* 'api' => [* ['name' => 'api', 'code_line' => 7444],* ['name' => 'api', 'code_line' => ...],* ['name' => 'api', 'code_line' => ...],* ],* 'cfnew' => [* ...* ]* ]*/->map(function ($groupedProjects) {return $groupedProjects->sum('code_line');})->sort()->reverse()->keys()->first();
经验,要么不用,用了就用到底,不要因为纠结用不用浪费太多时间,一般这种情况,你都写不出来,最后使用 foreach 解决了。

关于 collection 的一切,都可以在这本书里找到,Never write loop again

应该是 php 世界里最好用的 orm,作者也说过整个框架最难写的地方就是 eloquent 了.
参考 app.php
<?phpnamespace App;use Eloquent;class Post extends Eloquent{public function comments(){return $this->hasMany(Comment::class);}}
public function show($id){$post = Post::with('comments')->findOrFail($id); // 普通关联查询$post = Post::withCount('comments')->findOrFail($id); // 带上 count$post = Post::with(['comments' => function ($q) {return $q->latest('create_time');}])->findOrFail($id);}
public function recentComments(){return $this->hasMany(Comment::class)->where('created_at', '>', Carbon::yesterday());}
public function scopeSince($query, $since, $column = 'created_at'){return $query->where($column, '>', $since);}public function scopeSinceYesterday($query){return $this->since(Carbon::yesterday());}public function recentComments(){return $this->hasMany(Comment::class)->sinceYesterday();}
public function store(Request $request, Post $post){// not to do like this!Comment::create(['post_id' => $post->id,'content' => 'wow!']);// here$post->comments()->create(['content' => 'wow!']);}
class Post{public function newComment($attributes){return $this->comments()->create($attributes);}}
只有这样的写法才能叫 Eloquent.
BelongsTo || BelongsToMany
class Post{public function author(){return $this->belongsTo(Author::class);}}
class Post{public function newComment($author, $attributes){$comment = new Comment($attributes);$comment->author()->associate($author);return $this->comments()->save($comment);}}
这一直都是一个社区争论很多的话题
直接使用 eloquent
同时
添加 repository 层后
导致
整个应用生命周期
Eloquent
Millleware->Request->Controller->Eloquent->Response
Repository
Millleware->Request->Controller->Repository(Eloquent + Resquest)->Response
请食用 https://github.com/LingxiTeam/learn-eloquent 来进行深入实战学习。
目前内容并不太多,有时间都会抽空出来补充。
Not jus TDD(Test-driven development), we want BDD(Behavior-driven development)
class ExampleTestextendsTestCase{/*** A basic functional test example.* @return void*/public function testBasicExample(){$this->visit('/')->see('Laravel 5')->dontSee('Rails');}}
public function testSaveComment(){$comment = str_random(16);$this->post('/api/v1/comment', ['content' => $comment])->seeJson(['status_code' => '201','message' => 'Created.'])->seeInDatabase('comments', ['content' => $comment]);}
好的测试应该从 0 开始 (仅代表个人观点)
$factory->define(App\Models\Team\Contact::class, function (Faker\Generator $faker) {$birthday = $faker->date();return ['old_id' => mt_rand(100000, 999999),'team_id' => 1024,'name' => $faker->name,'nickname' => $faker->username,'email' => $faker->email,'birthday' => $birthday,'birth' => substr($birthday, -5),'source' => 'create'];});
Laravel 把 Vue 推向了世界,Vue 依赖于 ES6,加上 ES7 已经开始渐渐流行,你还不会 ES6?
所以, learn es6 by php.
在 es6 出来之前,javascript 是没有块级作用域这个概念的
function goTop(currentHeight){if (currentHeight > 100) {// go...var gone = true;console.log(gone);} else {console.log(gone);}}goTop(true); // truegoTop(); // undefined, 对于 js 初学者,这里就很迷惑,Uncaught ReferenceError: gone is not definedfunction goTop(currentHeight){var gone;if (currentHeight > 100) {// go...gone = true;console.log(gone);} else {console.log(gone);}}// in es6function goTop(currentHeight){if (currentHeight > 100) {// go...let gone = true;console.log(gone);} else {console.log(gone);}}goTop(); Uncaught ReferenceError: gone is not defined
至于 const,也是一个块级作用域的声明,其他和 php 一样,不过在 es6 里,并不会大写
const LANGUAGE = 'PHP';const language = 'javascript';
这里有个小坑
const DATA = [1,2,3];DATA[] = 4; // PHP Fatal error: Cannot use [] for reading
const data = [1,2,3];data.push(4); // [1,2,3,4]
投票显示 es6 中最需要的功能
var es5 = {go: function (a) {console.log(this)}}var es6 = {go: a => {console.log(this)}}// 区别在于箭头函数不会改变当前作用域,也就是 this.es6.go() // Window {speechSynthesis: ...}...es5.go() // Object {}es5.go.bind(this)() // Window {speechSynthesis: ...}...
function foo (a = 1) {console.log(a);}
和 php 一样,很多语言都引入了这个特性, es6 更强大就是了
function go (a, ...rest) {console.log(a, rest);}go (1,...[2,3,4]); // 1 [2, 3, 4]let obj = {a: 1,b: 2,c: 3}var a = obj.a;let {a, b, c} = obj;let {a, c} = obj;let {d} = obj; // undefined
const name = 'RryLee';console.log(`Hi!, i am ${name}`);// echo "Hi!, i am {$name}";
模板字符串还可以添加方法,可以自行了解
class People {construct (age, name) {this.age = age;this.name = name;}say () {console.log(`I am ${name} and ${age} years old.`)}}
class People{public function __construct (age, name) {$this->age = $age;$this->name = $name;}public function say() {echo 'I am ', name, ' and ', age, ' years old.'}}
// util.jsexport function sum(a, b) {return a + b;}// client.jsimport { sum } from './util.js'console.log(sum(1, 3)) // 4// util.jsexport default function {console.log('I am default function.')}// client.jsimport say from './util'say() // I am default function.// moreexport default {}export const app_name = 'lingxi'export class User {}export ...
以上基本涵盖了 es6 的全部基础用法,关于更好玩的 (Promise, Generator...),当然是要自己去用了。Oh, 基础的还有 for-of(用于遍历数组,以及 es6 的数据解构, set, map 等1) 和 for-in (便利对象)
function* range(start, end) {for (let i = start, j = 0; i <= end; i ++, j ++) {yield [i, j];}}for (let [num, i] of range(1, 10)) {console.log(`${i} => ${num}`);}