很多php开源系统都是基于Zend Optimizer的,所以我们需要先安装Zend Optimizer。 但在php5.3之后Zend Optimizer被Zend Guard Loader 取代了,所以我们就要安装Zend Guard Loader了。 zend官网,以下是安装 Zend Guard Loader的具体方法 安装前准备 1 2 uname -m #查看centos操作系统位数 php -v #查看PHP版本 在zend官网找到适合自己系统(32位或64位)的对应PHP版本的 Zend Guard Loader 下载并解压缩. 1 2 3 4 wget http://downloads.zend.com/guard/6.0.0/ZendGuardLoader-70429-PHP-5.4-linux-glibc23-x86_64.tar.gz tar -zxvf ZendGuardLoader-70429-PHP-5.4-linux-glibc23-x86_64.tar.gz cd ZendGuardLoader/ #进入解压后的目录 cat README.txt#查看 README 文档. 开始安装 复制对应PHP版本文件夹下的 ZendGuardLoader.so 到PHP安装目录(/etc/httpd/modules 目录或 /usr/lib/httpd/modules 目录, 这两个目录其实是同一个位置) 1 cp ZendGuardLoader.so /usr/lib/httpd/modules 编辑php配置文件.在 php.ini 文件末尾添加几行配置项. 1 2 3 4 5 vim /etc/php.ini zend_extension=/etc/httpd/modules/ZendGuardLoader.so zend_loader.enable=1 zend_loader.disable_licensing=0 zend_loader.obfuscation_level_support=3 检测配置文件是否配置正确 1 php -s 重启 Apache 或 Nginx 1 2 systemctl restart httpd 或 systemctl restart php-fpm from:https://www.cnblogs.com/Beyron/p/6189418.html
View Detailsioncube是业内优秀的php加密解密解决方案。和zend guard相比,ioncube具有如下优势: 1. 安全:zend guard的版本不是非常安全,网络上有破解使用zend,下面我们来看IonCube安装方法吧。 这两天安装whmcs的时候,出现了 requires the ionCube PHP Loader ioncube_loader_lin_5.4.so to be installed by the site administrator. 上面说的是没有安装ionCube,所以我们先来安装一下ionCube。 查看系统 uname -a 这里主要是查看一下系统是32位还是64位的,不然安装了也是没有用的。 下载ionCube 进入:http://www.ioncube.com/loaders.php ,根据你的系统是32位还是64位下载适当的软件包。 32位ionCube cd /usr/local wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86.tar.gz tar zxvf ioncube_loaders_lin_x86.tar.gz 64位ionCube cd /usr/local wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz tar zxvf ioncube_loaders_lin_x86-64.tar.gz 配置ionCube 修改php.ini 在文件尾部添加以下代码: [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_php的版本号.so" 列如 PHP5.1 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.1.so" PHP5.2 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.2.so" PHP5.3 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.3.so" PHP5.4 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.4.so" PHP5.5 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.5.so" PHP5.6 [ionCube Loader] zend_extension="/usr/local/ioncube/ioncube_loader_lin_5.6.so" 这里需要注意的是:如果有安装Zend Optimizer,安装ionCube会和Zend Optimizer可能发生冲突,须将Zend Optimizer的代码放在ionCube的后面。 验证ionCube 现在我们需要重启Apache2/php5-fpm(nginx)完成载入模块 重启WEB服务器 service apache2 restart service php5-fpm restart 重启完毕后,可以使用phpinfo来验证。或者直接建立一个PHP文件,内容如下: […]
View Details准备从系统中拷贝一些文件到U盘,插上U盘。 一、获得U盘的设备识别符 fdisk -l 啊哈,我看到了,是/dev/sdb1 二、熟练的挂载 mount /dev/sdb1 /mnt/usb Duang,竟然失败了,错误提示如下: unknown filesystem type ‘ntfs’ 三、原因 最小安装的系统中默认不识别NTFS格式的文件。 四、下载扩展包并解压 Open Source: NTFS-3G wget https://tuxera.com/opensource/ntfs-3g_ntfsprogs-2016.2.22.tgz 解压: tar -xvf ntfs-3g_ntfsprogs-2016.2.22.tgz 五、编译安装 三步曲:./configure && make && make install 六、挂载 mount -t ntfs-3g /dev/sda1 /mnt/usb 参考: https://www.cnblogs.com/yoyotl/p/6111531.html
View Details1、查找字符位置函数: strpos($str,search,[int]):查找search在$str中的第一次位置从int开始; stripos($str,search,[int]):函数返回字符串在另一个字符串中第一次出现的位置。该函数对大小写不敏感 strrpos($str,search,[int]):查找search在$str中的最后一次出现的位置从int 2、提取子字符函数(双字节) substr($str,int start[,int length]):从$str中strat位置开始提取[length长度的字符串]。 strstr($str1,$str2):从$str1(第一个的位置)搜索$str2并从它开始截取到结束字符串;若没有则返回FALSE。 stristr() 功能同strstr,只是不区分大小写。 strrchr() 从最后一次搜索到的字符处返回;用处:取路径中文件名 3、替换字符串 str_replace(search,replace,$str):从$str中查找search用replace来替换 str_irreplace(search,replace,$str): strtr($str,search,replace):这个函数中replace不能为”"; substr_replace($Str,$rep,$start[,length])$str原始字符串,$rep替换后的新 字符串,$start起始位置,$length替换的长度,该项可选 4、字符长度 int strlen($str) 5、比较字符函数 int strcmp($str1,$str2):$str1>=<$str2分别为正1,0,-1(字符串比较) strcasecmp() 同上(不分大小写) strnatcmp(“4″,”14″) 按自然排序比较字符串 strnatcasecmp() 同上,(区分大小写) 6、分割成数组函数 str_split($str,len):把$str按len长度进行分割返回数组 split(search,$str[,int]):把$str按search字符进行分割返回数组int是分割几次,后面的将不分割 expload(search,$str[,int]) 7、去除空格:ltrim、rtrim、trim 8、加空格函数 chunk_split($str,2);向$str字符里面按2个字符就加入一个空格; 9、chr、ord–返回指定的字符或ascii 10、HTML代码有关函数 nl2br():使\n转换为<br>。 strip_tags($str[,'<p>']):去除HTML和PHP标记 在$str中所有HTML和PHP代码将被去除,可选参数为html和PHP代码作用是将保留 可选参数所写的代码。 如:echo strip_tags($text, ‘<br><p>’); htmlspecialchars($str[,参数]):页面正常输出HTML代码参数是转换方式 11、字符大小写转换函数 strtolower($str) 字符串转换为小写 strtoupper($str) 字符串转换为大写 ucfirst($str) 将函数的第一个字符转换为大写 ucwords($str) 将每个单词的首字母转换为大写 12、数据库相关函数 addslashes($str):使str内单引号(’)、双引号(”)、反斜线(\)与 NUL 字符串转换为\’,\”,\\。 magic_quotes_gpc = On 自动对 get post cookie的内容进行转义 get_magic_quotes_gpc()检测是否打开magic_quotes_gpc stripslashes() 去除字符串中的反斜杠 13、连接函数 implode(str,$arr) 将字符串数组按指定字符连接成一个字符串;implode()函数有个别名函数join addcslashes —— 为字符串里面的部分字符添加反斜线转义字符 addslashes —— 用指定的方式对字符串里面的字符进行转义 bin2hex —— 将二进制数据转换成十六进制表示 chr —— 返回一个字符的ASCII码 chunk_split —— […]
View Details简介 Laravel 内置的 Eloquent ORM 提供了一个美观、简单的与数据库打交道的 ActiveRecord 实现,每张数据表都对应一个与该表进行交互的模型(Model),通过模型类,你可以对数据表进行查询、插入、更新、删除等操作。 在开始之前,确保在 config/database.php 文件中配置好了数据库连接。更多关于数据库配置的信息,请查看文档。 定义模型 我们从创建一个 Eloquent 模型开始,模型类通常位于 app 目录下,你也可以将其放在其他可以被 composer.json 文件自动加载到的地方。所有 Eloquent 模型都继承自 Illuminate\Database\Eloquent\Model 类。 创建模型实例最简单的办法就是使用 Artisan 命令 make:model:
1 2 |
php artisan make:model User |
如果你想要在生成模型时生成数据库迁移,可以使用 --migration 或 -m 选项:
1 2 3 |
php artisan make:model User --migration php artisan make:model User -m |
Eloquent 模型约定 现在,让我们来看一个 Flight 模型的例子,我们将用该类获取和存取数据表 flights 中的信息:
1 2 3 4 5 6 7 8 9 10 11 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { // } |
表名 注意我们并没有告诉 Eloquent 我们的 Flight 模型使用哪张表,默认规则是小写的模型类名复数格式作为与其对应的表名(除非在模型类中明确指定了其它名称)。所以,在本例中,Eloquent 认为 Flight 模型存储记录在 flights 表中。你也可以在模型中定义 table 属性来指定自定义的表名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { /** * 关联到模型的数据表 * * @var string */ protected $table = 'my_flights'; } |
主键 Eloquent 默认每张表的主键名为 id,你可以在模型类中定义一个 $primaryKey 属性来覆盖该约定。 此外,Eloquent 默认主键字段是自增的整型数据,这意味着主键将会被自动转化为 int 类型,如果你想要使用非自增或非数字类型主键,必须在对应模型中设置 $incrementing 属性为 false,如果主键不是整型,还要设置 $keyType属性值为 string。 时间戳 默认情况下,Eloquent 期望 created_at 和 updated_at 已经存在于数据表中,如果你不想要这些 Laravel 自动管理的数据列,在模型类中设置 $timestamps 属性为 false:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { /** * 表明模型是否应该被打上时间戳 * * @var bool */ public $timestamps = false; } |
如果你需要自定义时间戳格式,设置模型中的 $dateFormat 属性。该属性决定日期被如何存储到数据库中,以及模型被序列化为数组或 JSON 时日期的格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { /** * 模型日期列的存储格式 * * @var string */ protected $dateFormat = 'U'; } |
如果你需要自定义用于存储时间戳的字段名称,可以在模型中设置 CREATED_AT 和 UPDATED_AT 常量:
1 2 3 4 5 6 7 8 |
<?php class Flight extends Model { const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update'; } |
数据库连接 默认情况下,所有的 Eloquent 模型使用应用配置中的默认数据库连接,如果你想要为模型指定不同的连接,可以通过 $connection 属性来设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model { /** * The connection name for the model. * * @var string */ protected $connection = 'connection-name'; } |
获取模型 创建完模型及其关联的数据表后,就可以从数据库中获取数据了。将 Eloquent 模型看作功能强大的查询构建器,你可以使用它来流畅的查询与其关联的数据表。例如:
1 2 3 4 5 6 7 8 9 10 |
<?php use App\Flight; $flights = App\Flight::all(); foreach ($flights as $flight) { echo $flight->name; } |
添加额外约束 Eloquent 的 all 方法返回模型表的所有结果,由于每一个 Eloquent 模型都是一个查询构建器,你还可以添加约束条件到查询,然后使用 get 方法获取对应结果:
1 2 3 4 5 |
$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get(); |
注:由于 Eloquent 模型本质上就是查询构建器,你可以在 Eloquent 查询中使用查询构建器的所有方法。 集合 对 Eloquent 中获取多个结果的方法(比如 all 和 get)而言,其返回值是 Illuminate\Database\Eloquent\Collection 的一个实例,Collection 类提供了多个有用的函数来处理 Eloquent 结果集:
1 2 3 4 |
$flights = $flights->reject(function ($flight) { return $flight->cancelled; }); |
当然,你也可以像数组一样循环遍历该集合:
1 2 3 4 |
foreach ($flights as $flight) { echo $flight->name; } |
组块结果集 如果你需要处理数据量很大的 Eloquent 结果集,可以使用 chunk 方法。chunk 方法会获取一个指定数量的 Eloquent 模型“组块”,并将其填充到给定闭包进行处理。使用 chunk 方法在处理大量数据集合时能够有效减少内存消耗:
1 2 3 4 5 6 |
Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // } }); |
传递给该方法的第一个参数是你想要获取的“组块”数目,闭包作为第二个参数被传入用于处理每个从数据库获取的组块数据。 使用游标 cursor 方法允许你使用游标迭代处理数据库记录,一次只执行单个查询,在处理大批量数据时,cursor 方法可大幅减少内存消耗: […]
View Details简介 数据库查询构建器提供了一个方便的流接口用于创建和执行数据库查询。查询构建器可以用于执行应用中绝大部分数据库操作,并且能够在 Laravel 支持的所有数据库系统上工作。 注:流接口是一种设计模式,更多关于流接口模式的设计和使用方式,可查看这篇教程:PHP 设计模式系列 —— 流接口模式。 Laravel 查询构建器使用 PDO 参数绑定来避免 SQL 注入攻击,不再需要过滤以绑定方式传递的字符串。 获取结果集 从一张表中取出所有行 我们可以从 DB 门面的 table 方法开始,table 方法为给定表返回一个流式查询构建器实例,该实例允许你在查询上链接多个约束条件并返回最终查询结果。在本例中,我们使用 get 方法获取表中所有记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; class UserController extends Controller { /** * 显示用户列表 * * @return Response */ public function index() { $users = DB::table('users')->get(); return view('user.index', ['users' => $users]); } } |
get 方法返回包含结果集的 Illuminate\Support\Collection,其中每一个结果都是 PHP 的 StdClass 对象实例:  你可以像访问对象的属性一样访问字段的值:
1 2 3 4 |
foreach ($users as $user) { echo $user->name; } |
从一张表中获取一行/一列 如果你只是想要从数据表中获取一行数据,可以使用 first 方法,该方法将会返回单个 StdClass 对象:
1 2 3 |
$user = DB::table('users')->where('name', '学院君')->first(); echo $user->name; |
如果你不需要完整的一行,可以使用 value 方法从结果中获取单个值,该方法会直接返回指定列的值:
1 2 |
$email = DB::table('users')->where('name', '学院君')->value('email'); |
获取数据列值列表 如果想要获取包含单个列值的数组,可以使用 pluck 方法,在本例中,我们获取角色标题数组:
1 2 3 4 5 6 |
$titles = DB::table('roles')->pluck('title'); foreach ($titles as $title) { echo $title; } |
还可以在返回数组中为列值指定自定义键(该自定义键必须是该表的其它字段列名,否则会报错):
1 2 3 4 5 6 |
$roles = DB::table('roles')->pluck('title', 'name'); foreach ($roles as $name => $title) { echo $title; } |
组块结果集 如果你需要处理成千上百条数据库记录,可以考虑使用 chunk 方法,该方法一次获取结果集的一小块,然后传递每一小块数据到闭包函数进行处理,该方法在编写处理大量数据库记录的 Artisan 命令的时候非常有用。例如,我们可以将处理全部 users 表数据分割成一次处理 100 条记录的小组块:
1 2 3 4 5 6 |
DB::table('users')->orderBy('id')->chunk(100, function($users) { foreach ($users as $user) { // } }); |
你可以通过从闭包函数中返回 false 来终止组块的运行:
1 2 3 4 5 |
DB::table('users')->orderBy('id')->chunk(100, function($users) { // 处理结果集... return false; }); |
聚合函数 查询构建器还提供了多个聚合方法,如count, max, min, avg 和 sum,你可以在构造查询之后调用这些方法:
1 2 3 4 |
$users = DB::table('users')->count(); $price = DB::table('orders')->max('price'); |
当然,你可以联合其它查询子句和聚合函数来构建查询:
1 2 3 4 |
$price = DB::table('orders') ->where('finalized', 1) ->avg('price'); |
判断记录是否存在 除了通过 count 方法来判断匹配查询条件的结果是否存在外,还可以使用 exists 或 doesntExist 方法:
1 2 3 4 |
return DB::table('orders')->where('finalized', 1)->exists(); return DB::table('orders')->where('finalized', 1)->doesntExist(); |
查询(Select) 指定查询子句 当然,我们并不总是想要获取数据表的所有列,使用 select 方法,你可以为查询指定自定义的 select 子句:
1 2 |
$users = DB::table('users')->select('name', 'email as user_email')->get(); |
distinct 方法允许你强制查询返回不重复的结果集:
1 2 |
$users = DB::table('users')->distinct()->get(); |
如果你已经有了一个查询构建器实例并且希望添加一个查询列到已存在的 select 子句,可以使用 addSelect 方法:
1 2 3 |
$query = DB::table('users')->select('name'); $users = $query->addSelect('age')->get(); |
原生表达式 有时候你希望在查询中使用原生表达式,这些表达式将会以字符串的形式注入到查询中,所以要格外小心避免 SQL 注入。想要创建一个原生表达式,可以使用 DB::raw 方法:
1 2 3 4 5 6 |
$users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get(); |
注:原生语句会以字符串的形式注入查询,所以这里尤其要注意避免 SQL 注入攻击。 原生方法 除了使用 DB::raw 外,你还可以使用以下方法来插入原生表达式到查询的不同部分。 selectRaw selectRaw 方法可用于替代 select(DB::raw(…)),该方法接收一个可选的绑定数组作为第二个参数:
1 2 3 4 |
$orders = DB::table('orders') ->selectRaw('price * ? as price_with_tax', [1.0825]) ->get(); |
whereRaw / orWhereRaw whereRaw 和 orWhereRaw 方法可用于注入原生 where 子句到查询,这两个方法接收一个可选的绑定数组作为第二个参数:
1 2 3 4 |
$orders = DB::table('orders') ->whereRaw('price > IF(state = "TX", ?, 100)', [200]) ->get(); |
havingRaw / orHavingRaw havingRaw 和 orHavingRaw 方法可用于设置原生字符串作为 having 子句的值:
1 2 3 4 5 6 |
$orders = DB::table('orders') ->select('department', DB::raw('SUM(price) as total_sales')) ->groupBy('department') ->havingRaw('SUM(price) > 2500') ->get(); |
orderByRaw orderByRaw 方法可用于设置原生字符串作为 order by 子句的值:
1 2 3 4 |
$orders = DB::table('orders') ->orderByRaw('updated_at - created_at DESC') ->get(); |
连接(Join) 查询构建器还可以用于编写连接语句,关于 SQL 的几种连接类型,通过下图可以一目了然:  内连接(等值连接) 要实现一个简单的”内连接”,你可以使用查询构建器实例上的 join 方法,传递给 join 方法的第一个参数是你需要连接到的表名,剩余的其它参数则是为连接指定的列约束,当然,正如你所看到的,你可以在单个查询中连接多张表: […]
View Details简介 注:想要快速上手?只需要在新安装的 Laravel 应用下运行 php artisan make:auth 和 php artisan migrate,这两个命令会生成用户登录注册所需要的所有东西,然后在浏览器中访问 http://your-app.dev/register 即可。 Laravel 中实现登录认证非常简单。实际上,几乎所有东西 Laravel 都已经为你配置好了。配置文件位于 config/auth.php,其中包含了用于调整认证服务行为的、文档友好的选项配置。 在底层代码中,Laravel 的认证组件由“guards”和“providers”组成,Guard 定义了用户在每个请求中如何实现认证,例如,Laravel 通过 session guard 来维护 Session 存储的状态和 Cookie。 Provider 定义了如何从持久化存储中获取用户信息,Laravel 底层支持通过 Eloquent 和数据库查询构建器两种方式来获取用户,如果需要的话,你还可以定义额外的 Provider。 如果看到这些名词觉得云里雾里,大可不必太过担心,因为对绝大多数应用而言,只需使用默认认证配置即可,不需要做什么改动。 学院君注:通俗点说,在进行登录认证的时候,要做两件事,一个是从数据库存取用户数据,一个是把用户登录状态保存起来,在 Laravel 的底层实现中,通过 Provider 存取数据,通过 Guard 存储用户认证信息,前者主要和数据库打交道,后者主要和 Session 打交道(API 例外)。 数据库考量 默认情况下,Laravel 在 app 目录下包含了一个 Eloquent 模型 App\User,这个模型可以和默认的 Eloquent 认证驱动一起使用。如果你的应用不使用 Eloquent,你可以使用 database 认证驱动,该驱动使用 Laravel 查询构建器与数据库交互。 为 App\User 模型构建数据库表结构的时候,确保 password 字段长度至少有60位。保持默认字符串长度(255)是个不错的选择。 还有,你需要验证 users 表包含了 remember_token,该字段是个可以为空的字符串类型,字段长度为100,用于在登录时存储应用维护的“记住我” Session 令牌。  快速入门 Laravel 提供了几个预置的认证控制器,位于 App\Http\Controllers\Auth 命名空间下, RegisterController 用于处理新用户注册, LoginController 用于处理用户登录认证, ForgotPasswordController 用于处理重置密码邮件链接, ResetPasswordController 包含重置密码逻辑,每个控制器都使用 trait 来引入它们需要的方法。对很多应用而言,你根本不需要修改这些控制器:  路由 Laravel 通过运行如下命令可快速生成认证所需要的路由和视图:
1 2 |
php artisan make:auth |
新安装的应用运行该命令会生成布局、注册和登录视图,以及所有的认证路由,同时生成 HomeController 用于处理应用的登录请求。 打开 routes/web.php 路由文件会发现新增了两行: 登录注册相关路由都定义在上面 Auth::routes() 方法内。 视图 正如上面所提到的,php artisan make:auth 命令会在 resources/views/auth 目录下创建所有认证需要的视图。 make:auth 命令还创建了 resources/views/layouts 目录,该目录下包含了应用的基础布局文件。所有这些视图都使用了 Bootstrap CSS 框架,你也可以根据需要对其进行自定义。 认证 现在你已经为自带的认证控制器设置好了路由和视图,接下来我们来实现新用户注册和登录认证。你可以在浏览器中访问定义好的路由,认证控制器默认已经包含了注册及登录逻辑(通过trait)。 我们先来注册一个新用户,在浏览器中访问 http://blog.test/register,即可进入注册页面:  填写表单点击「Register」按钮即可完成注册。注册成功后页面跳转到认证后的页面 http://blog.test/home: 要测试登录功能,可以先退出当前用户,然后访问登录页面 http://blog.test/login:  使用我们之前注册的信息登录成功后,同样会跳转到 http://blog.test/home。 自定义路径 我们已经知道,当一个用户成功进行登录认证后,默认将会跳转到 /home,你可以通过在 LoginController、RegisterController 和 ResetPasswordController 中定义 redirectTo 属性来自定义登录认证成功之后的跳转路径:
1 2 |
protected $redirectTo = '/'; |
接下来,你需要编辑 RedirectIfAuthenticated 中间件的 handle 方法来使用新的重定向 URI。 如果重定向路径需要自定义生成逻辑可以定义一个 redirectTo 方法来取代 redirectTo 属性:
1 2 3 4 5 |
protected function redirectTo() { return '/path'; } |
注:redirectTo 方法优先级大于 redirectTo 属性。 […]
View Details简介 Laravel 提供了多个辅助函数来帮助我们在应用中生成 URL。这些函数主要用于在视图模板和 API 响应中构建链接,或者生成重定向响应。 快速入门 生成 URL url 辅助函数可用于为应用生成任意 URL,并且生成的 URL 会自动使用当前请求的 scheme(HTTP or HTTPS) 和 host 属性:
1 2 3 4 5 6 |
$post = App\Post::find(1); echo url("/posts/{$post->id}"); // 输出 http://example.com/posts/1 |
访问当前 URL 如果没有传递路径信息给 url 辅助函数,则会返回一个 Illuminate\Routing\UrlGenerator 实例,从而允许你访问当前 URL 的信息:
1 2 3 4 5 6 7 8 9 |
// 获取不带请求字符串的当前 URL... echo url()->current(); // 获取包含请求字符串的当前 URL... echo url()->full(); // 获取上一个请求的完整 URL... echo url()->previous(); |
上述每一个方法都可以通过 URL 门面进行访问,例如:
1 2 3 4 |
use Illuminate\Support\Facades\URL; echo URL::current(); |
命名路由 URL route 可用于生成指向命名路由的 URL。命名路由允许你生成不与路由中定义的实际 URL 耦合的 URL,因此,当路由的 URL 改变了,route 函数调用不需要做任何更改。例如,假设你的应用包含一个定义如下的路由:
1 2 3 4 |
Route::get('/post/{post}', function () { // })->name('post.show'); |
要生成指向该路由的 URL,可以这样使用 route 辅助函数:
1 2 3 4 |
echo route('post.show', ['post' => 1]); // 输出 http://example.com/post/1 |
通常我们会使用 Eloquent 模型的主键来生成 URL,因此,可以传递 Eloquent 模型作为参数值,route 辅助函数会自动解析模型主键值,所以,上述方法还可以这么调用:
1 2 |
echo route('post.show', ['post' => $post]); |
控制器动作 URL action 辅助函数用于为控制器动作生成 URL,和路由中的定义一样,你不需要传递完整的控制器命名空间,却而代之地,传递相对于App\Http\Controllers 命名空间的控制器类名即可:
1 2 |
$url = action('HomeController@index'); |
如果控制器方法接收路由参数,你可以将其作为第二个参数传递给该方法:
1 2 |
$url = action('UserController@profile', ['id' => 1]); |
参数默认值 对某些应用而言,你可能希望为特定 URL 参数指定请求默认值,例如,假设多个路由都定义了一个 {locale} 变量:
1 2 3 4 |
Route::get('/{locale}/posts', function () { // })->name('post.index'); |
每次调用 route 辅助函数都要传递 locale 变量显得很笨拙,所以,我们可以在当前请求中使用 URL::defaults 方法为这个参数定义一个默认值,我们可以在某个路由中间件中调用该方法以便可以访问当前请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\URL; class SetDefaultLocaleForUrls { public function handle($request, Closure $next) { URL::defaults(['locale' => $request->user()->locale]); return $next($request); } } |
一旦设置好 locale 参数的默认值之后,就不必在通过 route 辅助函数生成 URL 时每次指定传递的值了。 from:http://laravelacademy.org/post/8787.html
View Details简介 Blade 是由 Laravel 提供的非常简单但功能强大的模板引擎,不同于其他流行的 PHP 模板引擎,Blade 在视图中并不约束你使用 PHP 原生代码。所有的 Blade 视图最终都会被编译成原生 PHP 代码并缓存起来直到被修改,这意味着对应用的性能而言 Blade 基本上是零开销。Blade 视图文件使用 .blade.php 文件扩展并存放在 resources/views 目录下。 模板继承 定义布局 使用 Blade 的两个最大优点是模板继承和片段组合,开始之前让我们先看一个例子。首先,我们测试“主”页面布局,由于大多数 Web 应用在不同页面中使用同一个布局,可以很方便的将这个布局定义为一个单独的 Blade 页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!-- 存放在 resources/views/layouts/app.blade.php --> <html> <head> <title>应用名称 - @yield('title')</title> </head> <body> @section('sidebar') 这里是侧边栏 @show <div class="container"> @yield('content') </div> </body> </html> |
正如你所看到的,该文件包含典型的 HTML 标记,不过,注意 @section 和 @yield 指令,前者正如其名字所暗示的,定义了一个内容片段,而后者用于显示给定片段的内容。 现在我们已经为应用定义了一个布局,接下来让我们定义继承该布局的子页面吧。 继承布局 定义子页面的时候,可以使用 Blade 的 @extends 指令来指定子页面所继承的布局,继承一个 Blade 布局的视图可以使用 @section 指令注入内容到布局定义的内容片段中,记住,如上面例子所示,这些片段的内容将会显示在布局中使用 @yield 的地方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- 存放在 resources/views/child.blade.php --> @extends('layouts.app') @section('title', 'Laravel学院') @section('sidebar') @parent <p>Laravel学院致力于提供优质Laravel中文学习资源</p> @endsection @section('content') <p>这里是主体内容,完善中...</p> @endsection |
在本例中,sidebar 片段使用 @parent 指令来追加(而非覆盖)内容到继承布局的侧边栏,@parent 指令在视图渲染时将会被布局中的内容替换。 注:与之前的示例相反,sidebar 部分以 @endsection 结束而不是 @show,@endsection 指令只是定义一个 section 而 @show 指令定义并立即返回这个 section。 Blade 视图可以通过 view 方法直接从路由中返回:
1 2 3 4 |
Route::get('blade', function () { return view('child'); }); |
这样在浏览器中访问 http://blog.test/blade,就可以看到页面显示如下: 现在页面还很粗糙,没有任何样式,后面学习前端组件后可以回来完善。 组件 & 插槽 组件和插槽给内容片段(section)和布局(layout)带来了方便,不过,有些人可能会发现组件和插槽的模型更容易理解。首先,我们假设有一个可复用的“alert”组件,我们想要在整个应用中都可以复用它:
1 2 3 4 5 6 |
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> {{ $slot }} </div> |
{{ $slot }} 变量包含了我们想要注入组件的内容,现在,要构建这个组件,我们可以使用 Blade 指令 @component:
1 2 3 4 |
@component('alert') <strong>Whoops!</strong> Something went wrong! @endcomponent |
有时候为组件定义多个插槽很有用。下面我们来编辑alert组件以便可以注入“标题”,命名插槽可以通过“echoing”与它们的名字相匹配的变量来显示:
1 2 3 4 5 6 7 |
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> <div class="alert-title">{{ $title }}</div> {{ $slot }} </div> |
现在,我们可以使用指令 @slot 注入内容到命名的插槽。任何不在 @slot 指令中的内容都会被传递到组件的 $slot变量中:
1 2 3 4 5 6 7 8 |
@component('alert') @slot('title') Forbidden @endslot You are not allowed to access this resource! @endcomponent |
当我们在浏览器中查看这个组件内容的话,对应输出如下: 这段代码的意思是通过组件名 alert 去查找对应的视图文件,装载到当前视图,然后通过组件中 @slot 定义的插槽内容去渲染插槽视图中对应的插槽位,如果组件没有为某个插槽位定义对应的插槽内容片段,则组件中的其他不在 @slot 片段中的内容将会用于渲染该插槽位,如果没有其他多余内容则对应插槽位为空。 传递额外数据到组件 有时候你可能需要传递额外数据到组件,出于这个原因,你可以传递数组数据作为第二个参数到 @component 指令,所有数据都会在组件模板中以变量方式生效:
1 2 3 4 |
@component('alert', ['foo' => 'bar']) ... @endcomponent |
组件别名 如果 Blade 组件存储在子目录中,你可能想要给它们起别名以便访问。例如,假设有一个存放在 resources/views/components/alert.blade.php 的 Blade 组件,你可以使用 component 方法将这个组件设置别名为 alert(原名是 components.alert)。通常,这个操作在 AppServiceProvider 的 boot 方法中完成:
1 2 3 4 |
use Illuminate\Support\Facades\Blade; Blade::component('components.alert', 'alert'); |
组件设置别名后,就可以使用如下指令来渲染:
1 2 3 4 |
@alert(['type' => 'danger']) You are not allowed to access this resource! @endalert |
如果没有额外插槽的话也可以省略组件参数:
1 2 3 4 |
@alert You are not allowed to access this resource! @endalert |
数据显示 可以通过两个花括号包裹变量来显示传递到视图的数据,比如,如果给出如下路由:
1 2 3 4 |
Route::get('greeting', function () { return view('welcome', ['name' => '学院君']); }); |
那么可以通过如下方式显示 name 变量的内容:
1 2 |
你好, {{ $name }}。 |
当然,不限制显示到视图中的变量内容,你还可以输出任何 PHP 函数的结果,实际上,可以将任何 PHP […]
View Details简介 由于 HTTP 协议本身是无状态的,上一个请求与下一个请求无任何关联,为此我们引入 Session 来存储用户请求信息以解决特定场景下无状态导致的问题(比如登录、购物)。Laravel 通过简洁的 API 统一处理后端各种 Session 驱动,目前开箱支持的流行后端驱动包括 Memcached、Redis 和数据库。 学院君注:Laravel 并没有使用 PHP 内置的 Session 功能,而是自己实现了一套更加灵活更加强大的 Session 机制,核心逻辑请参考 Illuminate\Session\Middleware\StartSession 这个中间件,因此在 Laravel 应用中不要试图通过 $_SESSION 方式去获取应用的 Session 值,这是徒劳的。另外,还有一个大家都感到困惑的问题,就是在 Laravel 的控制器构造函数中是无法获取应用 Session 数据的,这是因为 Laravel 的 Session 通过 StartSession 中间件启动,既然是中间件就会在服务容器注册所有服务之后执行,而控制器们的构造函数都是在容器注册服务的时候执行的,所以这个时候 Session 尚未启动,有何来的获取数据呢?解决办法是将获取 Session 数据逻辑后置或者在构造函数中引入在 StartSession 之后执行的中间件。 配置 Session 配置文件位于 config/session.php。默认情况下,Laravel 使用的 Session 驱动为 file 驱动,这对许多应用而言是没有什么问题的。在生产环境中,你可能考虑使用 memcached 或者 redis 驱动以便获取更佳的 Session 性能,尤其是线上同一个应用部署到多台机器的时候,这是最佳实践。 Session 驱动用于定义请求的 Session 数据存放在哪里,Laravel 可以处理多种类型的驱动: file – Session 数据存储在 storage/framework/sessions 目录下; cookie – Session 数据存储在经过安全加密的 Cookie 中; database – Session 数据存储在数据库中 memcached / redis – Session 数据存储在 Memcached/Redis 缓存中,访问速度最快; array – Session 数据存储在简单 PHP 数组中,在多个请求之间是非持久化的。 注:数组驱动通常用于运行测试以避免 Session 数据持久化。 驱动预备知识 数据库 当使用 database 作为 Session 驱动时,需要设置表包含 Session 字段,下面是该数据表的表结构声明:
1 2 3 4 5 6 7 8 9 |
Schema::create('sessions', function ($table) { $table->string('id')->unique(); $table->unsignedInteger('user_id')->nullable(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->text('payload'); $table->integer('last_activity'); }); |
你可以使用 Artisan 命令 session:table 在数据库中创建这张表:
1 2 3 |
php artisan session:table php artisan migrate |
Redis 在 Laravel 中使用 […]
View Details