一般刚接触tp5.1的,会很不适应,虽然版本号只是比5.0多了0.1,但是差别挺大,废弃了不少方法,官方的教程又很简单,很多东西没说全,在此鄙视一下框架作者,最起码体谅一下小白嘛,搞了好多天才把5.1使用vendor里面引入第三方包的问题搞好,惨啊,在此分享,让后来的小白别走太多弯路。
一,1、在thinkPHP 5.1.X新版取消了Loader::import方法以及import和vendor助手函数,推荐全面采用命名空间方式的类以及自动加载机制,如果必须使用请直接改为php内置的include或者require语法。(抱怨一下,这种问题要在官方文档里面说明一下嘛,鄙视作者,整5.1的时候这些方法挨个试了一遍,又是搜又是看教程结果全部卵用,无奈。)
原来的import("Vendor.Classes.PHPExcel.IOFactory");或Vendor('phpoffice.phpexcel.Classes.PHPExcel.IOFactory');方法已经不再使用。
二,在thinkPHP 5.1.X中的处理方法,必须使用composer方式安装第三方模块。否则在vendor目录下的内容无法自动加载。也就是到了这一版必须用Composer,方法加载去掉了,其实这样也好,比较靠拢主流框架,比如laravel,如果用好TP5.1在转向laravel很容易,而且用工具管理包,也符合现在的开发潮流,像node各种工具包管理,在此虽然刚接触很不爽,但是支持吧。
怎么安装Composer 就不说了,教程一堆,反正不成功再搜再搞,就差不多了。
三,主要内容:重点说一下php namespace和use,能够成功在TP5.1中引入第三方包,命名空间太重要了,必须明白到底是咋回事,单单明白namespace还不行,use的用法和规则也缺一不可,我当时就只了解了namespace,什么大空间,子空间,依然不成功,是因为use用的不对。
1.namespace后命名的定义不区分大小写
2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。
这个其实没有用命名空间的时候,就不加就OK了,其实反斜杠就是用来区分此时的空间和别的空间,你编写类的空间就是主空间,你导入的第三方包的空间是子空间,你new不加反斜杠就是告诉编译器你这个类是在主空间里,加反斜杠就是告诉编译器,让他到反斜杠写的空间里找这个类,这个规则叫PSR4规范,是php一些官方组织规定的,不规定也不行,那个大公司开发个框架这样搞,那个那样搞,为了php和谐发展没办法,因为原语言php很简单,很多东西没规定好,只能后来的组织去规范,小白们接受吧。哈哈。
4.类在指定命名空间下, new类时,一定要带上指定的命名空间。
没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。
//1.php 第三方类,使用了命名空间
namespace one;
class Person{
function __construct(){
echo 'I am one!';
}
}
-------------------------------------------------------------------------------------------
//name.php 你自己写的类
require_once './1.php';
new \one\Person(); //输出 I am one!;
new \Person(); //代码报错:Fatal error: Class 'Person' not found
这个上面的方式使用Require_once导入文件路径,再用new 加反斜杠,实现成功实例化类。对于TP5以上来说他有自动的实例化类功能,不用Require_once 只要写new \one\Person(); 也是可以实例化类的,内部的魔术方法会自动根据反斜杠的路径找类,但是这种方式只能把使用的文件类放入extend文件中,其他文件夹就不管用了,框架只会在这个文件夹下找,试过其他新创建的文件夹不管用,要是用这种方式就要把包中的文件php文件单独拷贝到extend下可以新建util文件夹放在里面,还要修改php文件的命名空间,因为之前的命名空间是composer自动导入的那个文件夹,修改成现在的 namespace util;比如使用的时候不用use,直接 new \util\类名(); 就可以实例化成功。
new的时候反斜杠必须在最前面。new \one\Person();这样,而如果用use方式,最前面不能有反斜杠 one\Person();,哈哈,别扭啊,
namespace test\person; 这里test\person;只是命名空间的名字和声明的类毫无关系,不要把person当成是Person
class Person{
function __construct(){
echo 'I am test!';
}
}
new \test\person\Person(); //命名空间里person无法代表类名
正确做法就是,命名空间名字加上类名才是正确的new 后面的内容,才能正确实例化,否则又找不到类错误。
3.在new的时候,我也犯嘀咕,正确的反斜杠实例化名字是啥,其实就是第三方类里面namespace的名字加你实例化类的名字,就是完整正确的new,在此再说一遍就是namespace的名字和类名是分开的,一个是一个,这样规定也是为了一个脚本里面一个命名空间比如有两个类,三个类,可以用这个命名空间随便实例化任意一个类。
四,说了require_once加namespace方式,接下来说namespace和use 方式。
1,这必须明白use的功能是什么?
在命名空间字符串过长时,使用use可以相应的缩短命名空间。
看到了吧用use其实就是简写的意思,之前我一直没用对,不知道正确怎么用,
new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。
namespace animal\dog;
class Life{
function __construct(){
echo 'dog life!';
}
}
//你使用的时候
use animal\dog; //a 完整引入文件的namespace 名字
new dog\Life(); //B 使用use的情况下是简写形式,只需写最后一个字符dog,而且和不使用use实例化的时候不一样第一个字符不需要加反斜杠,这个要记住,直接写dog加反斜杠加你要实例化的类Life。
使用use后,new类时,最前面没有反斜杠。
没使用use时,命名空间最前面有反斜杠
use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的:
use animal\dog;
相当于
use animal\dog as dog;
2.namespace后面不建议加类名,但use后可以。
use animal\dog\Life as dog;
new dog();
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。
也就是说在TP5.1中使用namespace和use时,我导入的rbac权限验证
第三方包
namespace gmars\rbac;
use gmars\nestedsets\NestedSets;
use think\Db;
use think\Exception;
class Rbac
{
/**
-------------------------下面自己写的类,上面是rbac包类----------------------------------------------------
namespace app\index\Controller;
use gmars\rbac; //use的是第三方包的namespace名字
class Login extends Controller
{
public function login(){
实例化的时候
$rbacObj=new rbac\Rbac(); //就是use的名字最后一个字符rbac 加上你要实例化的类名。
五,这里还要说一下composer,如果你项目有报错,找不到包什么的可以去看项目跟目录里面的composer.json这里是你导入第三方类的表,看看有没有这个包在里面
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.*",
"gmars/tp5-rbac":"dev-master",
"gmars/tp5-nestedsets": "dev-master",
"topthink/think-captcha": "^2.0",
"topthink/think-migration":"^1.0",
"phpmailer/phpmailer": "^6.0"
},
在你composer require tp5-rbac 出现下载进度,就说明在安装中,如果没有有错误信息,就直接在compose.json文件中require大括号里面手动加上 "gmars/tp5-rbac":"dev-master", 然后命令composer update ,就会安装了,这个很多教程都有说,其实用composer刚开始觉得挺高大上,其实就是json文件,composer里php类,运用php自动加载类的机制实现的,没什么太魔幻的。正确使用namespace和use后,就很方便了。
在此推荐https://www.cnblogs.com/drunkhero/p/namespace.html
文章中引用了宅码农的关于namespace和use 的内容,他解释的很好,如果没太明白我说了,看看他这个,很详细。