php代码之面向对象基础一
这篇文章不适合于初学者看,对php有一定了解的可以看一下,补充或者温故一下php面向对象里的一些特性。
一.何为面向对象?
介个问题,虽然略知一二,却感觉依然拿不出手,只能说将万事万物皆看为对象,只有在开发中才能体会出何为面向对象,只说也是徒然,但因为php大多用在web开发,所以,即使不使用面向对象也能运行的不错,之前在做c++开发时,设计给你个功能界面,看到这个界面,第一件事就是像美工切图一样的切成一个个的对象,然后,确定各个对象之间的关系,最后进行开发,哪儿都充斥着此思想。
什么是类?什么是对象?
类是一组集合的抽象,什么集合呢?是一组具有相似特性和操作的对象的集合。
对象是某一个类的具体实例。
毕业时候可能我会背给面试官听,可现在,虽然感觉理解的还是想书本上的语句一样的俗,但起码不用再靠脑细胞说出这两个定义。
二.php中的类结构
php中类也是那些访问控制符,也是有属性和方法。
class Person { private $name = "PersonName"; public static $gender = "PersonGender"; public function test(){ echo $this->name, '<br />'; } };
构造函数的名称为__construct,在构造函数这里我想强调的有以下几点:
1. php不会像其他语言(c++或者java)那样,当实例化子类的时候会自动调用你的父类构造函数,php里需要手动调用父类的构造函数,这儿牵扯到继承,可以先看一下继承方面的东西。
class Person{ public funciton __construct(){ echo 'Person construct<br />'; } }; class Teacher extends Person{ public function __construct(){ //parent::__construct(); echo 'Teacher construct<br />'; } }; $t1 = new Teacher; //生成Teacher对象
运行结果:
Teacher construct
如果想要在生成子类时初始化父类的一些数据,需要手动调用父类的构造函数,打开注释行即可。
2. 一个类中不能写两个参数不同的构造函数。
这儿牵扯到php中的一些规定,其他语言中,以下写法是正确的:
class Person{ public funciton __construct(){ echo 'Person construct<br />'; } public function __construct($param){ echo 'Person with param construct<br />'; } };
而在php是不允许的,究其根源为php是一种弱语言类型,对于类型的限制不是很敏感,进而提供了__call和func_get_args函数机制,因而可以用如下的方式实现:
class Person{ public function __construct(){ $param = func_get_arg(); //获取参数数据 $param_num = func_num_args(); //获取参数个数 if($param_num == 0){ }else if($param_num == 1){ if(is_array($param[0])){ //... } }else{ //... } } };
三.析构函数
析构函数是用于在此实例对象结束时,自动调用的函数,可以写入一下释放内存的语句来为实例的死亡画上完美的句号,这儿与构造相同,有继承关系时必须手动调用父类的析构,一个类中只有一个析构。
四.控制访问符
public:公共访问符,在类内,子类内,类外都可以访问此属性或方法。
protected:受保护的访问符,只能在类内和其子类内访问此属性或方法,在类外不能访问。
private:私有访问符,只能在本类内访问,属于本类私有东东,不能继承,不能重载,任何人访问不了。
五.魔术方法__get和__set
这两个方法的功能:对受保护和私有属性访问的一个访问器,可以对从类外接收到的数据进行安全性和合理性的校验。
__set方法接收两个参数,第一个是属性名称,第二个是要赋的新值。
__get方法接收一个参数,属性名称。
1. public属性能提供在类外修改属性的服务,因此,对于public属性,不会走__get和__set流程。
class D{ public $name = 'D name'; protected $gender = 'male'; private $age = 18; public function __set($name, $value){ echo '__set<br />'; //if(in_array($name, ['name', 'gender', 'age'])) $this->$name = $value; } public function __get($name){ echo '__get<br />'; //if(!in_array($name, ['name', 'gender', 'age'])) return NULL; return $this->$name; } };
运行结果:
new D name //name为public属性,不会走get和set __set __get new D gender __set __get new D age
2. 我们也可以加入数据校验的功能,打开注释就可以进行校验。
3.两个方法必须是public访问,否则会提示错误,我们可以从这两个函数的功能来出发思考,就不难想象为什么需要public访问控制。
六.继承
终于到了可以让你的菊花开苞的特性,没有继承,所有类都是渣渣,因为有了继承,所以...问题就特么的一大波一大波的来啦...让我们来深入浅出一下此继承特性。
什么继承就不说了吧,文章的开头就有一个继承的小示例。
有了继承会出现什么问题呢?想一下,如果B继承了A...真的是难以想象...
1. 构造函数,这个放心,跟继承没有太多关系,相当于两个类里的构造函数,但是怎么也有个父子关系啊,不能把事做的太绝,所以,上面讲过,如果有需要,可以手动调用父类的构造函数,可以看下上面的示例。
2.单方向继承,继承是单方向的,子类可以从父类继承,但父类却不能从子类继承特性,示例:
class A{ public $attr1; public function oper1(){ } }; class B extends A{ public $attr2; public function oper2(){ } }; //子类可以继承父类 $b = new B; $b->oper1(); $b->attr1 = 'attr1 value'; $b->oper2(); $b->attr2 = 'attr2 value'; //父类不能继承子类 $a = new A; $a->oper2();//出错 $a->attr1();//出错
3. 重载,一提到php的重载就特别别扭,因为他的重载放到其他语言里叫做重写overwrite,我还是习惯将这个特性说为重写,大家随便。
public重载:
class E{ public $attr1 = 'E attr1 value'; public function oper1(){ echo 'E oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ //parent::oper1(); echo 'F oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; $f = new F; $f->oper1();
运行结果:
F oper1
attr1 value = F attr1 value
F继承了E并且重写了E的attr1和oper1,因此,在调用oper1时,$this->attr1显示F attr1 value,如果打开注释parent::oper1调用父类的Oper1方法,运行结果如下:
E oper1
attr1 value = F attr1 value //attr1属性已经被子类重写的attr1属性覆盖
F oper1
attr1 value = F attr1 value
可以看出子类重写父类的属性和方法后,会覆盖父类相应的属性和方法。
private重载
class E{ private $attr1 = 'E attr1 value'; public function oper1(){ echo 'E oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ parent::oper1(); echo 'F oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; $f = new F; $f->oper1();以上代码只变动了一处地方,就是把父类$attr1的访问属性变成private,那重载机制如何执行呢?先看运行结果:
E oper1
attr1 value = E attr1 value //父类私有的属性
F oper1
attr1 value = F attr1 value
之前我们说过,private属性和方法子类是继承不了的,这种情况,遵循一个原则:
private属性在那个类里调用的,就显示哪个类里的属性值。
示例中的parent::oper1方法调用的是E类的oper1方法,在E的oper1方法内又调用了$this->attr1,attr1是private并没有被子类继承,因此,调用的就是类E里的attr1属性值。
protected重载与public重载一致
类属性的继承
class G{ public static $attr1 = 'G attr1 value'; public function oper1(){ echo 'G oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; $h = new H; $h->oper1();
运行结果:
G oper1
attr1 value = G attr1 value
H oper1
attr1 value = H attr1 value
其实不管G类的attr1属性是public还是private,结果都一样。
个人是这么理解的,类属性可以继承,但谈不上重载,那关于子类调用父类的属性也有一规则:
self或者parent只代表本类,因此,根据这一原则可以断定,属性的值一定是本类属性的值,与子类无关。(特殊情况时php的静态延迟加载机制)。
七.静态延迟加载
既然已经提到了静态延迟加载,就趁热打铁讲一下,H和G的例子大家已经看了,那我就是想要在子类中调用父类的东东怎么办?静态延迟加载就是解决这个问题,请看两个示例:
示例1:
还是H和G类的例子
class G{ public static $attr1 = 'G attr1 value'; public function oper1(){ echo 'G oper1<br />'; echo 'attr1 value = ', static::$attr1, '<br />'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; $h = new H; $h->oper1();运行结果:
G oper1
attr1 value = H attr1 value
H oper1
attr1 value = H attr1 value
上面代码只是将G类里的self::$attr1改写成了static::$attr1,运行结果就不一样了
示例2:
class I { public static function who(){ echo __CLASS__, '<br />'; } public static function test(){ static::who(); } }; class J extends I{ public static function who(){ echo __CLASS__,'<br />'; } };
运行结果:
J
通过这两个例子,可以好好的领悟一下static的静态延迟绑定。
写的有点多,主要是因为一牵扯继承就停不下来....面向对象还有一些只是点,后面有时间再补上吧...谢谢,如若有错误的地方,敬请大家指出,随时更正,谢谢!!

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中