为什么PHP应该使用 Repository Pattern设计模式

Repository 模式

为了保持代码的整洁性和可读性,使用Repository Pattern 是非常有用的。事实上,我们也不必仅仅为了使用这个特别的设计模式去使用Laravel,然而在下面的场景下,我们将使用OOP的框架Laravel 去展示如何使用repositories 使我们的Controller层不再那么啰嗦、更加解耦和易读。下面让我们更深入的研究一下。

不使用 repositories

其实使用Repositories并不是必要的,在你的应用中你完全可以不使用这个设计模式的前提下完成绝大多数的事情,然而随着时间的推移你可能把自己陷入一个死角,比如不选择使用Repositories会使你的应用测试很不容易,具体的实现将会变的很复杂,下面我们看一个例子。HousesController.php

这是一个很典型的一段代码使用Eloquent和数据库交互,这段代码工作的很正常,但是controller层对于Eloquent而言将是紧耦合的。在此我们可以注入一个repository创建一个解耦类型的代码版本,这个解耦的版本代码可以使后续程序的具体实现更加简单。

使用 repositories

其实完成整个repository模式需要相当多的步骤,但是一旦你完成几次就会自然而然变成了一种习惯了,下面我们将详细介绍每一步。

1. 创建 Repository 文件夹

首先我们需要在app文件夹创建自己Repository文件夹repositories,然后文件夹的每一个文件都要设置相应的命名空间。

2: 创建相应的 Interface

第二步创建对应的接口,其决定着我们的repository类必须要实现的相关方法,如下例所示,在此再次强调的是命名空间一定要记得加上。HouseRepositoryInterface.php

3: 创建对应的 Repository

现在我们可以创建我们repository类 来给我们干活了,在这个类文件中我们可以把我们的绝大多数的数据库查询都放进去,不论多么复杂。如下面的例子 DbHouseRepository.php

4: 创建后端服务提供

首先你需要理解所谓服务提供,请参考手册服务提供者 BackendServiceProvider.php

当然你也可以新建一个文件夹主要放我们的provider相关文件。 上面一段代码主要说的是,当你在controller层使用类型提示HouseRepositoryInterface, 我们知道你将会使用DbHouseRepository.

5: 更新你的Providers Array

其实在上面的代码中,我们已经实现了一个依赖注入,但如果我们要使用在此我们是需要手动去写的,为了更为方面,我们需要增加这个providers到 app/config/app.php 中的 providers数组里面, 只需要在最后加上App\Repositories\BackendServiceProvider::class,

6:最后使用依赖注入更新你的controller

当我们完成上面的那些内容之后,我们在Controller只需要简单的调用方法代替之前的复杂的数据库调用,如下面内容:HousesController.php

 

Laravel 在视图间共享数据及视图Composer

1、在视图间共享数据

除了在单个视图中传递指定数据之外,有时候需要在所有视图中传入同一数据,即我们需要在不同视图中共享数据。要实现这一目的,需要使用视图工厂的share方法。

全局帮助函数viewresponse类似,如果传入参数,则返回Illuminate\View\View实例,不传入参数则返回Illuminate\View\Factory实例。所以我们可以通过在服务提供者的boot方法中使用如下方式实现视图间共享数据:

我们在routes.php中定义两个路由

然后在resources/views目录下创建一个home.blade.php视图文件,内容如下

再创建一个hello.blade.php视图文件:

在浏览器中分别访问http://laravel.app:8000/testViewHellohttp://laravel.app:8000/testViewHome,则都能解析出$sitename的值。

2、视图Composer

有时候我们想要在每次视图渲染时绑定一些特定数据到视图中,比如登录用户信息,这时候我们就要用到视图Composer,视图Composer通过视图工厂的composer方法实现。该方法的第二个回调参数支持基于控制器动作和闭包函数两种方式。

简单起见,我们还是基于AppServiceProvider,不去单独创建服务提供者,这里我们传递闭包参数(控制器动作参考视图文档)

修改hello.blade.php视图文件:

在浏览器中访问http://laravel.app:8000/testViewHello,输出内容如下:

你也可以传递数据到多个视图:

甚至所有视图(使用通配符*):

注:更多视图方法请参考Laravel核心源码:Illuminate\View\View.phpIlluminate\View\Factory.php

php出现Cannot modify header information解决方法

这样的语句,很显然,造成这个原因是因为setcookie造成的,查了一下网上,有如下的解释:      cookie本身在使用上有一些限制,例如:
1.呼叫setcookie的敘述必須放在<html>标签之前
2.呼叫setcookie之前,不可使用echo
3.直到網頁被重新載入後,cookie才會在程式中出現
4.setcookie函数必須在任何資料輸出至浏览器前,就先送出
5.……
基於上面這些限制,所以執行setcookie()函数时,常會碰到”Undefined index”、”Cannot modify header information – headers already sent by”…等問題,解決”Cannot modify header information – headers already sent by”这个錯誤的方法是在产生cookie前,先延缓資料输出至浏览器,因此,您可以在程式的最前方加上ob_start();这个函數。这样就可以解决 了。        如果要加上ob_start()的话,不大可行,程序都写完了,才来改这个似乎有点郁闷..       发现提示这个错误的时候,我就在想我本地怎么没提示这个问题呢,还以为是PHP.ini配置不一样,想想又不对,都是差不多的..
于是看看后面跟的那句”output started at….”意思是在setcookie之前已经在另一处有输出了,于是找到output started at后面跟的那个文件,看到第一行是空白的,然后才是<?php 这样开始,难道会是这一行的问题吗??我本地也有这一行呢,去掉,刷新再试,呵呵,果然出在这里,不再提示warning了
解决完毕!

解决方法二:
编辑php.ini,然后将output_buffering将其值由原来的4096(也可能为off)改为on,重新启动php-fpm就好了。

Nginx运行Laravel伪静态的配置

ngin下不配置的话路由会404的。。。

 

使用 Laravel API 文档生成器扩展包自动为项目生成 API 文档

1、简介&安装

Laravel API 文档 生成器 扩展包可以基于 Laravel 应用路由自动生成项目 API 文档。

我们使用Composer安装这个扩展包:

安装完成后需要到 config/app.php 中注册服务提供者

2、使用

基本示例

下面我们来演示如何使用这个扩展包自动为项目生成API文档,其原理是通过扫描 routes.php 为指定路由生成相应API文档,比如我们的路由文件定义了一个路由如下

这个路由对应的控制器方法定义如下:

需要指出的是,Laravel API 生成器通过action方法上的注释生成 API 相应的描述信息。我们使用扩展包提供的 api:generate 命令来实现 API 文档生成:

该命令的意思是扫描路由中匹配 api/v1/* 的规则并为相应控制器方法生成API文档,该命令会在 public 目录下生成一个 docs 目录以及相应文件,我们在浏览器中通过 http://blog.dev/docs/index.html (我的域名是blog.dev)来查看API文档:

带响应数据的示例

上面是一个最简单的示例,大部分时候我们的action会返回HTTP响应,这种情况下API文档又是如何显示的呢?

我们在路由文件 routes.php 中定义一个路由如下:

对应的控制器方法定义如下:

我们在action中简单返回一个带字符串信息的Response,要生成该方法的API文档,还是要运行 api:generate 命令:

运行完成后,再次访问 http://blog.dev/docs/index.html ,就可以看到API响应测试信息:

在右下角我们可以看到响应数据信息。

如果需要认证用户才能调用API,可以在生成API文档的时候加个 --actAsUser 选项并指定用户ID:

带参数的API

下面我们来看一个更加复杂的例子,有时候我们提交POST请求到某个API时会带参数,这个时候如何生成带参数的API文档信息呢?很简单,我们只需按照之前的正常逻辑走,然后运行下 api:generate 命令即可。

我们定义一个post请求路由如下:

在定义应控制器方法之前我们先通过如下命令生成一个请求类:

这会在 app/Http/Requests 目录下新生成一个 TestRequest 类,我们编辑该类的rules 方法如下:

接下来再去控制器中定义相应方法:

我们在控制器方法中通过依赖注入传入我们刚刚创建的 TestRequest 类。

最后还是按部就班,通过 api:generate 命令生成新的API文档:

在浏览器中访问 http://blog.dev/docs/index.html ,在页面中我们可以看到带参数的API文档信息:

更多使用

如果觉得默认的API文档模板太丑陋,该扩展包还提供了 api:update 命令修改默认API文档模板,其操作流程是先修改 index.md 文件(位于 public/docs/source/index.md ),修改好了之后通过如下命令保存修改:

这个功能很简单,这里就不做演示了。了解更多请参考该扩展的GitHub项目: https://github.com/mpociot/laravel-apidoc-generator/

打印 Laravel 的 SQL 语句

在使用 Laravel 的 Eloquent 进行数据查询的时候,很多小伙伴都想看到背后执行的 SQL 语句到底是什么样的,这小笔录就是解决这个小问题的:

Providers/AppServiceProvider.php 的 boot 方法添加一行代码就行:

这个时候,只要你刷新页面,有执行到 SQL 查询,就可以到 storage/logs 文件夹下面的 laravel log 查看具体的 sql 语句了。

Run Gulp Tasks in Laravel Easily with Elixir

As a developer(frontend or backend), you might have probably or still use a task runner, for those who haven’t used a task runner, a task runner is simply an automated tool for performing repetitive tasks like concatenation, minification, unit testing, linting e.t.c.

There are awesome task runners on github available for everyone to use, but out of all the task runners, gulp and grunt really stand out as they are very popular, mature and mostly used by developers.

For this article, gulp is a requirement and if you are new to gulp, this article should be extremely useful.

 

懒得复制了,查看更多请访问

https://scotch.io/tutorials/run-gulp-tasks-in-laravel-easily-with-elixir

ThinkPHP 分页中带入查询(搜索)条件

很多情况下,分页还会带入查询条件,而这时查询往往是不固定的。例如常见的搜索,需要根据用户查询的关键字来进行检索,在搜索结果太多时,就需要将搜索结果进行合理分页。

ThinkPHP 分页可以很容易的实现对不固定查询参数的支持。具体实现是给分页类的 parameter 属性赋值或者直接实例化分页类时传入查询参数。下面以例子来说明。

parameter 属性赋值
例如要检索用户表中状态为 1 (status=1) 并且电子包含 163 的用户,当提交表单时(注意表单是 GET 方式提交),形成的 URL 地址大致如下:

http://www.cnsecer.com/index.php/Index/search/status/1/email/163

在搜索操作(search)中主要代码如下

在页面的分页链接中,可以看到地址(如第 2 页)为:

http://www.cnsecer.com/index.php/Index/search/status/1/email/163?status=1&email=163&p=2

可以看见分页链接中已经包含了需要检索的 status=1&email=163 条件。当然,实际解析后的地址应该是:

http://www.cnsecer.com/index.php/Index/search/status/1/email/163/p/2/

这是因为 ThinkPHP 分页类对 URL 的处理还不够完美造成的。要对此进行改进,参看《ThinkPHP 定制分页风格及URL》。

传入 parameter 参数
带入查询条件的分页关键就是设置分页类的 parameter 属性值。除了上例中给 parameter 属性赋值外,也可以直接在实例化类的时候将 parameter 参数传入,两种方式结果是一致的:

提示
上述例子只是用于讲述分页中带入查询条件的使用,因此未对检索的关键字进行进行安全处理。实际使用中在进行查询之前,应对用户输入的关键词做安全性方面的处理。

laravel把数据共享给所有的视图

有时候,你可能需要共享一份数据给所有的视图,你应该使用视图工厂(View Factory)的share方法。通常,我们在服务提供者的boot方法中调用share方法来完成注册。如果需要同时共享多份数据,你可以将所有对share方法的调用放在一个服务提供者中(AppServiceProvider或者其他),或者单独的为每个需要共享的数据建立一个服务提供者。

 

请教thinkphp如何使用utf8mb4

最近在做一个与emoji表情有关的东西,emoji需要4个字节来存储,所以需要使用到utf8mb4,但现在我发现怎么都插入不了这个emoji的字符。保存到数据库之后都会变更为????
请问有谁有相关的经历的,告诉我怎么处理。无尽感谢。

 

解决方法

数据库的、表的、字段的编码统统设为utf8mb4

数据连接配置为
‘DB_CHARSET’=> ‘utf8mb4’,
字段字符集 也需修改为 uf8mb4
才能正常存储

nginx提示No input file specified怎么办

1、 php.ini(/usr/local/php/etc/php.ini)的配置中中找到
cgi.fix_pathinfo=0
将其改成
cgi.fix_pathinfo=1
2、nginx配置文件/etc/nginx/conf/nginx.conf中注意以下部分

路径需要根据你主机主目录的实际情况填写
配置完以上部分,重启一下nginx和php-fpm,问题成功
另外,还可能跟 路径或者权限 有关系,或者SCRIPT_FILENAME 变量没有被正确的设置(这在nginx是最常见的原因)
1)如果html也出现404错误,那么就是document root 设置的有问题
2)检查脚本文件的权限, 可能PHP或者web server不能读取它
3)SCRIPT_FILENAME设置错误
解决方法:
排除了SCRIPT_FILENAME设置错误,那问题就出现在目录文件夹及文件的权限访问上。重新设置了文件www用户组的权限,立即可以访问后台了。在这里再次特别感谢 久酷 童鞋。
设置权限的SSH命令则是

补充:我的SCRIPT_FILENAME设置参数

vim fcgi.conf (SCRIPT_FILENAME的目录)

 

 

discuz X3.1以及X3.2论坛搬家完美详细教程

很多站长第一次做网站的时候,无奈选择了速度不是很稳定的空间,慢慢会发现有很多物美价廉速度相当快的空间

这个时候,站长在网站搬家的过程中就会遇到很多困难,今天给大家详细讲解一下discuz论坛搬家的详细过程

第一步:备份网站数据
进入后台—站长—数据库—备份,数据备份类型选择“Discuz!和 UCenter数据”,备份成功以后,数据自动保存在data文件夹下。

第二步:网站文件下载
把整个网站文件打包(虚拟主机管理控制面板一般都有整站压缩和解压的功能,在控制面板选择压缩,压缩之后的文件一般在FTP DB文件夹里面,然后把压缩包下载到本地电脑,如果虚拟主机没有在线压缩功能那就直接使用FTP下载文件到本地保存。

第三步:整理下载到本地的网站文件
1.把下载下来的文件里面的下列文件删除,请完全放心删除掉这几个文件,重新装上的时候会自动产生新的文件。
/install/install.lock  (有的下载下来之后就没有这个文件,如果没有就不用管)
/config/config_global.php
/config/config_ucenter.php
/uc_server/data/config.inc.php

2.到官方下载一个Discuz! X3的安装包,把 upload里的/install/文件夹复制过来覆盖你下载下来的网站文件。

3.把从官方下载下来的Discuz! X3安装包里面的 utility/restore.php 文件放到你网站文件的/data/文件夹内,这是用于数据库还原。

第四步:将整理好的网站文件包上传到新主机空间(放网页资料的文件夹下)
建议压缩之后在使用FTP上传,上传完成之后进入虚拟主机控制面板在线解压,这样可以节约很多时间,目前几乎所有的虚拟主机都有在线解压功能,格式一般是rar格式,不过有的部分虚拟主机如linux主机就只支持.zip格式,所以打包前请注意。

第五步:域名解析及空间绑定域名
进入域名控制面板把域名解析到你新的虚拟主机IP上,然后在进入虚拟主机空间绑定域名。

第六步:重新安装discuz
http://你的域名/instal/进行安装,填入你新的虚拟主机数据库名和用户名及数据库密码,注意数据库的数据表前缀和以前一样,一般你之前的数据表如果没有改动的话,你重新安装的时候默认的就是和你以前的一样,所以可以不用改。当你安装的时候可能会提示要你删除data/install.lock这个文件才可以继续安装,那么你可以进入FTP删除之后然后返回安装页面刷新一下再继续安装,这就可以安装了。

第七步:还原数据库
安装成功后,用你安装的时候填写的管理员帐号和密码登录,进入后台—站长—数据库—恢复—数据恢复,选中要恢复的数据然后点击右边导入,点击确定即可恢复数据,为了安全起见当成功恢复数据后进入FTP删除/data/restore.php这个文件。
有时候进入之后数据恢复,发现没有可供还原的数据,那么你可以看到下面这一行文字,那你直接点击你的网址在浏览器当中恢复数据即可,为了安全起见当成功恢复数据后进入FTP删除/data/restore.php这个文件。
您可以在本页面数据备份记录处导入备份恢复数据,也可以通过在浏览器中执行 http://www.你的域名.com/data/restore.php 恢复数据

第八步:检查UCenter能否登陆
提示:1、检查UCenter 访问地址设置是否正确(没有更换域名做第六步安装,一般不会出错)
2、创始人密码和admin管理员密码不是同一个,创始人密码是上面第六步重新安装discuz程序时设置的密码。

第九步:检查UCenter应用是否通讯成功
后台——UCenter——应用管理,查看通讯情况,若通讯失败,请检查通信密钥设置是否相同。
后台——站长——UCenter设置,检查UCenter 通信密钥是否和UCenter应用设置相同

第十步:更新缓存
数据还原成功之后,在后台退出帐号,用你原来的后台管理员帐号登陆,进入后台更新缓存,网站搬家成功结束。

微信公众号开发之多客服用法

如果使用多客服的话,需要把用户消息转接至微信服务器

如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,如果希望将消息转发到多客服系统,则需要开发者在响应包中返回MsgType为transfer_customer_service的消息,微信服务器收到响应后会把当次发送的消息转发至多客服系统。 示例代码

 

PHP关于反射的一个例子

先上代码吧

PHP反射对应的文档:http://php.net/manual/zh/reflection.examples.php#101585

 

就这么多吧  具体怎么用把手册里面的文档过一遍就行了。

 

laravel unique validation update

If you use route model binding, you can do something like this:

参考这篇文章:https://laracasts.com/discuss/channels/requests/laravel-5-validation-request-how-to-handle-validation-on-update