1.oop基本概念:
{通过析构函数分析变量或者对象的生命周期}:
通过__destruct{echo $this->$name}玉洁,学敏的例子,
可以清楚分析到,PHP的OOP构建对象的过程其实就是个压栈的过程,
最先生成的对象被压入栈底,最后生成的对象位于栈顶,
所以当我们人工执行析构函数或者程序执行到最后一行即将自动执行析构函数的时候,
释放内存的顺序是“最后进来的先被销毁,后进先出”、
变量的生命周期也是这样。
这就是栈的强大之处。深切体会到了
2.对象链:
(1).$obj->a()->b();
//a方法中return $this,那么 $obj->a()这家伙又是一个对象了,那么它再去调用b()就很合理了,
这就是连续调用多个函数的对象链技术。
所以遇到很奇葩的技术细节,关键是紧扣“基本技术的底层原理”,借助底层原理去“套”,看“奇葩”到底是怎么做到的。
(2).面试题:{关键是对于函数调用和返回值的深刻理解}
function show(){ echo "bbb"; }
echo "aaaaaa".show();
//我们把这两行代码在PHP文件中写好,在浏览器中一运行,发现输出的结果竟然是:bbbaaaaaa
//原理解析:第一,函数如果没有返回值,那么默认调用返回的就是空,
即:echo "aaaaaa".show();这里aaaaaa后面接了个空{因为show无返回值,就无输出嘛}
第二,分析函数调用的顺序,echo "aaaaaa".show(); 这句话直到;才算完成,才会执行这句话的结果,
而调用show()在分号结束前就已经完成,所以必定是show()的“bbb”先输出。
综上两点,输出结果是bbbaaaaaa
(3).变量的生命周期:
超全局变量:页面任何地方可以任意使用:
1.超全局数组:我们之前学习的$_GET,$_POST,{见php基础手册的超全局数组}
2.预定义变量:PHP内置的一些变量,php推荐用超全局数组访问预定义变量,所以可以直接不使用预定义变量
全局变量:页面任何地方可用,但如果想穿梭进入函数内部生效,需要global关键字标识。{OOP中基本不用它}
局部变量:函数内部有效,出了定义的局部范围就失效。{主要是写函数传入变量}
3.书写规范:
(1).类的首单词大写,匈牙利命名法
(2).几个关键字:extends,
3.几个方法调用:
(1).子类在其定义内部,使用父类的方法:
parent::show();//子类调用父类的show方法;
(2).一个类定义好之后,在定义之外的任何地方,都可以直接“类名::方法{或者属性}”来调用类的方法和属性。
比如:class page {//类定义部分}; parent::show();
//这种方法是为了处理某些紧急情况:{一般不用}
比如某些对象还没来得及实例化,或者在对象被实例化之前就需要用到类的属性,我们就不得不自己用 "类::"这个格式
(3).类的一些测试函数:{这些方法目的是:查PHP的手册嘛,大哥,手册解决一切嘛}
get_class();//获取对象当前的类
get_parent_class;//获取对象的父类
get_object_vars;//获取对象的属性
get_class_methods;//获取类或者对象的方法
原理解释:
//内存里有一个区域: 代码区:存放各类函数{}里面的内容和类的方法。
还有一个区域很有意思: 常量区:
类和对象生成时空的原理:
1->类只是定义,不占空间,而对象会申请空间。
2->对象的指针{对象名称}放在栈区,而对象的实际数据{属性}放在堆区,{方法}却不在堆区,它位于代码区。
3->所以属性只有对象被实例化才能访问,而方法,通过类本身{不实例化对象}就能直接使用方法。
get_class_methods;所以PHP官方手册在查询methods的时候,只给了一个函数就查到了对象和类的方法,
这是因为 {类的方法的查询} 和 {对象的方法的查询}都是一个函数搞定的
因为方法不依赖于对象,它在代码去,
属性之所以依赖对象,是因为它的赋值必须通过对象。
method_exists();//对象和类是否存在某方法; //用法见PHP手册
property_exists();//对象或类中是否存在某个属性,但是取不到值,因为属性只有在对象生成赋值才有值。
is_object();//判断类型是否为对象
对象名 instanceof 类名();//判断某个对象是从这个祖先类实例化出来的?
//例如: $yujie instanceof Person();
class_exists();//测试类是否存在
interface_exists();//测试接口是否存在
(4).魔术方法:
见之前在慕课网的OOP笔记,写接口的做的笔记。
4.实现类{工厂}模式:见NewPage那个例子{分页类的完美版}
function M($className){
$obj = new $className; //但这里需要注意$className这个类里面如果有需传参的构造方法,那么就要改改了。
return $obj;//返回这个生产的对象名
}
function P(Usb $objName){ //Usb $objName这里对这个传入的对象有限制。
$objName->dosomething();
}
$Upan = new Upan();
$Udisk = new Udisk();//Upan Udisk都是Usb的子类
P($Upan);
P($Udisk);
//这时候如果有个Ufs不是Usb的子类,但具体细节和Usb的实现细节一模一样,但它不符合标准,所以它调用P被禁止了
P($Ufs);//这里编译会报错
{单例}模式:见我在慕课网的PHP开发接口里写的关于model的单例模式
5. 抽象方法和接口:
*只要定义了抽象方法,类必须被声明为抽象类。{抽象类里面既有抽象方法,也有普通方法}
*抽象方法没有实现部分,即{}不能有。
所以抽象类只是底层设计的一个标准声明层,不能直接new,必须在抽象类的子类中实现这些抽象方法。
*接口:里面只有一些方法的声明{默认就等价于抽象方法},没有属性{这是接口和抽象方法唯一的不同}
6.PHP的多态:
*1:一个子类对同一个父类不同的实现过程
*2:java里面引入到PHP的这个工厂模式,
function U(Usb $objName){ //Usb $objName这里对这个传入的对象有限制。
$objName->dosomething();
}
$Upan = new Upan();
$Udisk = new Udisk();//Upan Udisk都是Usb的子类
U($Upan);
U($Udisk);
//这时候如果有个Ufs不是Usb的子类,但具体细节和Usb的实现细节一模一样,但它不符合标准,所以它调用U被禁止了
U($Ufs);//这里编译会报错
*3:通过函数传入参数的限制,实现多态。
7.魔术方法里面有个很神奇的函数,必须掌握啊,终于搞清楚为什么TP这么神奇,有“自动加载机制”这种神器了。
为毛?连autoload这种神器都有了,什么自动加载都不是神话了,O(∩_∩)O哈哈哈~
<?
// 这里本来有 include($className.'class.php');但是我现在没写,我就直接写下面实例化model了,会报错吗???
//注意啊,类名是Model,那么文件名就是Model.class.php,终于看到这种命名的优势了:有利于自动加载include文件啊
function __autoload($className){//魔术方法的参数,系统自动智能捕获,发现Model他就会把Model捕获过来的,不要担心
include($className.'class.php');
}
$user = new Model('user');
//大家请看,虽然我没有include这个类文件Model.class.php,而且也没有调用__autoload();
但$user这个对象它就是安全生成了,为什么???__autoload发现我没include就给我自动include文件了
?>
//再看个例子,你会发现,__autoload灰常灰常强大,用起来很爽;
<?
function __autoload($className){
include($className.'class.php');
//等价于只要下面我new任何一个类,都会自动把该类的文件包含进来,比如:
//include('Model.class.php');
//include('Page.class.php');
$user = new Model('user');
$page1 = new Page('page1');
//之后就想怎么使用$user,$page1这两个对象的什么方法都可以了。哈哈,真的太强大了。
}
?>
//所以__autoload就是为了自动加载类的神器,这个功能的开发者真的很厉害啊,
不过,为了避免我们在__autoload内部还要加工“类文件名”{因为系统只能智能捕获“类名”},
我们为了让系统一探测到“类名”就可以拿到“类文件名”,必须书写规范:类名是 "Model" ,那么文件名就是 "Model+固定后缀"
//其实魔术方法,就是不需要我们手工调用,系统通过判断,在"特定时机",自动激发,自动去调用一些方法:
{比如 __construct在系统创建对象的那一刻自动被激发,__autoload在程序一开始自动激发,__tostring在程序把一个对象当字符串 时自动激发}
8.const和static
* const是类常量 | {外部访问:“类名::常量名”, 内部调用: “self::常量名”}
* static是类静态变量 | {外部访问:“类名::变量名”, 内部调用: “self::变量名”或者“static::变量名”}
* const和static调用的方法要记住:"{无论类的内外部}":都允许直接"类名::常量名",
原因是 const和static都不是依赖对象,他们在内存中都位于 {常量区},他们都是直接为类服务,是全体对象的公用东西。
但是我们会发现如果在类内部,只要类名改了,那么调用const和static都需要修改类名,那多累!!!
所以我们想,能不能学$this,$this代表本对象,那么有没有一个变量代表本类,额。。。。还真有!!!
就是self,
所以以后但凡是在{类定义的"内部"},又需要本类出场的地方,都用self代替,它不会因为类名修改了就影响const和static
* static还有自己的一个的一个独特调用方式:static::hello();//这个在"类内部"就表示调用静态方法hello();
9.final:
* 在{方法和类}前面加一个final,表示该方法和类都是最终版本,该方法禁止重载,该类禁止被继承
* 应用场景:某个类已经是最终版本,为保证该类的安全性,那么就加个final
10.PDO学习: