


多对多关系的 tag 事例
前言
上一节,我们对 flash message 的使用做一个讲解,了解到什么是 flash message,而且会进行简单的使用。本节,我们对数据库多对多的形式,以文章 tags 作为例子进行讲解。
说明
开发环境:Windows 7
Laravel 版本: 5+
IDE: Phpstorm
数据库在,之前我们就对 Laravel 的Eloquent 和Migration 做过两节介绍,而且在Relationships 讲过数据表之间的外键关系,那也是基本的一对多。
本节我们对数据库中的多对多进行一个讲解,而且所举的例子就是 tags ,文章标签。
tags 的引入
现在咱们博客的基本功能已经有了,写文章,发表文章等。但是随着文章越来越多,文章的筛选和管理就成了问题,要是能有 tag 标记每篇文章的关键词,这对文章的管理将是一个很大的改善。
下面我们就来看一下 Eloquent 是怎么实现给文章 tagging 的。
打开的 Article.php ,还记得当初我们为每篇文章(Article)关联作者(User)是在哪个方法吗?算了,你也回答不了,就在最下面的 user() 方法,里面写了一句 belongsTo 就指明了文章所属。该语句与 hasMany 是相对的,文章只能 belongsTo 一个作者,但是一名作者可以 hasMany 文章,就是这么个关系。
但是在 tag 这里,belongsTo 和 hasMany 就有点讲不通了,一篇文章不能只 belongsTo 一个 tag ,应该是 belongsToMany tags 才通顺。
所在在 user() 方法下面再价一个 tags() 方法,如下所示:
public function tags(){ return $this->belongsToMany('App\Tag');}
下面呢,我们去创建一个 Tag Eloquent model吧。
创建 Tag model类和 Tag 表
在命令行下输入命令:php artisan make:model Tag。
再在命令行下输入命令: php artisan make:migration create tagtable –create=tags
打开这个 create tagtable.php ,在这里创建 tag 表的一些属性或者说列:
public function up(){ Schema::create('tags', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); Schema::create('article_tag',function(Blueprint $table){ $table->integer('article_id')->unsigned()->index(); $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade'); $table->integer('tag_id')->unsigned()->index(); $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); $table->timestamps(); });}public function down(){ Schema::drop('tags'); Schema::drop('article_tag');}
之所以还同时创建一个 pivot table (即“ article_tag ”表),就是为了相当于一个快速查找表,能把 article 和 tag 联系在一张表中,方便查取。
接下来对 migration 进行执行,在命令行中执行:php artisan migrate
接下来打开 Tag.php,刚创建的。
既然 tag 和 Article 是多对多的关系,那么在 Tag model 类中也应有一个指向 article 的方法:
public function articles(){ return $this->belongsToMany('App\Article'); |}
保存后,打开命令行,通过 tinker 来验证是否成功:php artisan tinker
>>> $tag = new App\Tag;=> App\Tag {#646}>>> $tag->name='personal';=> "personal">>> $tag->save();=> true>>> App\Tag::all()->toArray();=> [ [ "id" => 1, "name" => "personal", "created_at" => "2016-04-30 13:48:49", "updated_at" => "2016-04-30 13:48:49", ], ]
关联 article 和 tag
下面我们尝试关联一下这两个表。
在 tinker 模式下:
>>> App\Tag::all()->toArray();=> [ [ "id" => 1, "name" => "personal", "created_at" => "2016-04-30 13:48:49", "updated_at" => "2016-04-30 13:48:49", ], ]>>> $article=App\Article::first();=> App\Article {#659 id: "1", user_id: "1", created_at: "2016-03-20 15:05:18", updated_at: "2016-03-20 15:05:18", title: "谭晓龙创建的文章", body: "真的是", published_at: "2016-03-28 00:00:00", }>>> $article->toArray();=> [ "id" => 1, "user_id" => "1", "created_at" => "2016-03-20 15:05:18", "updated_at" => "2016-03-20 15:05:18", "title" => "谭晓龙创建的文章", "body" => "真的是", "published_at" => "2016-03-28 00:00:00", ]>>> $article->tags()->attach(1);Illuminate\Database\QueryExceptionwithmessage 'SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: article_tag.created_at (SQL: insert into "article_tag" ("article_id", "tag_id") values (1, 1))'
这里的 $article->tags()->attach(1),就是通过 tags() 方法将 id=1 的 tag 绑定(attach)到该 article 上。
不幸的是,我们报错了,原因就是没有创建时间。改一下吧。
打开 Article.php ,找到 tags() 方法,修改成如下:
public function tags(){ return $this->belongsToMany('App\Tag')->withTimestamps();}
就是这样。
再执行 attach 命令:
>>> $article = App\Article::first();=> App\Article {#655 id: "1", user_id: "1", created_at: "2016-03-20 15:05:18", updated_at: "2016-03-20 15:05:18", title: "谭晓龙创建的文章", body: "真的是", published_at: "2016-03-28 00:00:00", }>>> $article->tags()->attach(1); => null>>> DB::select('select * from article_tag');=> [ {#650 +"article_id": "1", +"tag_id": "1", +"created_at": "2016-04-30 14:00:31", +"updated_at": "2016-04-30 14:00:31", }, ]>>> $article->tags->toArray();=> [ [ "id" => 1, "name" => "personal", "created_at" => "2016-04-30 13:48:49", "updated_at" => "2016-04-30 13:48:49", "pivot" => [ "article_id" => "1", "tag_id" => "1", "created_at" => "2016-04-30 14:00:31", "updated_at" => "2016-04-30 14:00:31", ], ], ]>>> $article->toArray();=> [ "id" => 1, "user_id" => "1", "created_at" => "2016-03-20 15:05:18", "updated_at" => "2016-03-20 15:05:18", "title" => "谭晓龙创建的文章", "body" => "真的是", "published_at" => "2016-03-28 00:00:00", "tags" => [ [ "id" => 1, "name" => "personal", "created_at" => "2016-04-30 13:48:49", "updated_at" => "2016-04-30 13:48:49", "pivot" => [ "article_id" => "1", "tag_id" => "1", "created_at" => "2016-04-30 14:00:31", "updated_at" => "2016-04-30 14:00:31", ], ], ], ]>>> $article->tags->lists('name'); => Illuminate\Support\Collection {#653 all: [ "personal", ], }
给文章关联完之后,我们再给 tag 关联文章:
>>> $tag=App\Tag::first();=> App\Tag {#666 id: "1", name: "personal", created_at: "2016-04-30 13:48:49", updated_at: "2016-04-30 13:48:49", }>>> $tag->articles->toArray();=> [ [ "id" => 1, "user_id" => "1", "created_at" => "2016-03-20 15:05:18", "updated_at" => "2016-03-20 15:05:18", "title" => "谭晓龙创建的文章", "body" => "真的是", "published_at" => "2016-03-28 00:00:00", "pivot" => [ "tag_id" => "1", "article_id" => "1", ], ], ]
哈哈,tag 以及你个自动被绑定到了 article ,直接现实了出来。
总结
这就是今天要讲的内容,相当于是对 Relationship 的扩展和应用吧。
希望今天的内容你能吸收消化。共勉。

ThesecrettokeepingaPHP-poweredwebsiterunningsmoothlyunderheavyloadinvolvesseveralkeystrategies:1)ImplementopcodecachingwithOPcachetoreducescriptexecutiontime,2)UsedatabasequerycachingwithRedistolessendatabaseload,3)LeverageCDNslikeCloudflareforservin

You should care about DependencyInjection(DI) because it makes your code clearer and easier to maintain. 1) DI makes it more modular by decoupling classes, 2) improves the convenience of testing and code flexibility, 3) Use DI containers to manage complex dependencies, but pay attention to performance impact and circular dependencies, 4) The best practice is to rely on abstract interfaces to achieve loose coupling.

Yes,optimizingaPHPapplicationispossibleandessential.1)ImplementcachingusingAPCutoreducedatabaseload.2)Optimizedatabaseswithindexing,efficientqueries,andconnectionpooling.3)Enhancecodewithbuilt-infunctions,avoidingglobalvariables,andusingopcodecaching

ThekeystrategiestosignificantlyboostPHPapplicationperformanceare:1)UseopcodecachinglikeOPcachetoreduceexecutiontime,2)Optimizedatabaseinteractionswithpreparedstatementsandproperindexing,3)ConfigurewebserverslikeNginxwithPHP-FPMforbetterperformance,4)

APHPDependencyInjectionContainerisatoolthatmanagesclassdependencies,enhancingcodemodularity,testability,andmaintainability.Itactsasacentralhubforcreatingandinjectingdependencies,thusreducingtightcouplingandeasingunittesting.

Select DependencyInjection (DI) for large applications, ServiceLocator is suitable for small projects or prototypes. 1) DI improves the testability and modularity of the code through constructor injection. 2) ServiceLocator obtains services through center registration, which is convenient but may lead to an increase in code coupling.

PHPapplicationscanbeoptimizedforspeedandefficiencyby:1)enablingopcacheinphp.ini,2)usingpreparedstatementswithPDOfordatabasequeries,3)replacingloopswitharray_filterandarray_mapfordataprocessing,4)configuringNginxasareverseproxy,5)implementingcachingwi

PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Chinese version
Chinese version, very easy to use
