hi
本來是雄心壯志的要干活的,哪知天有不測,早上大陰天起不來,中午又回寢室折騰衣服(做女工啊,牛不牛)沒睡午覺,這樣的迷糊狀態,怎麼科研,寫這個好了。
1、PHP的OOP編程
4.7 多態
--定義
由於接口的方法實現有多種多樣,這種特性稱之為多態
--栗子
function eat($obj){
if($obj instanceof ICanEat){
$obj->eat("FOOD"); // 不需要知道到底是Human還是Animal,直接吃就行了
}else{
echo "Can't eat!\n";
}
}
$man = new Human();
$monkey = new Animal();
// 同樣的代碼,傳入接口的不同實現類的時候,表現不同。這就是為什麼成為多態的原因。
eat($man);
eat($monkey);
--小結
/**
* 多態
* 1. 只要某個對象實現了接口(instanceof),就可以直接在對象上調用接口的方法
*/
4.8 抽象類
--問題
連接接口的類,某些方法都是相同的,那麼是否能夠允許類中不實現,而是在接口中實現。
比如,人和動物吃東西不同,但呼吸相同。
--栗子
abstract class ACanEat{ //關鍵字改變
abstract public function eat($food);//需要類自行實現的,前面加上abstract關鍵字
public function breath(){
echo "Breath use the air.<br/>";
}
}
class Human extends ACanEat{ //實現接口用implenments,這裡用extends
public function eat($food){
echo "Human eating ".$food."<br/>";
}
}
class Animal extends ACanEat{ //實現接口用implenments,這裡用extends
public function eat($food){
echo "Animal eating ".$food."<br/>";
}
}
$xiaoming=new Human();
$xiaohei=new Animal();
$xiaoming->breath();$xiaoming->eat("food");
$xiaohei->breath();$xiaohei->eat("shit");
--小結
/**
* 抽象類
* 1. 抽象類允許類裡面的部分方法暫時沒有具體實現,這些方法我們成為抽象方法
* 2. 一旦類裡面有抽象方法,這個類就必須是抽象類
* 3. 抽象類跟接口一樣,不能直接實例化為對象
*/
五、魔術方法
5.1 簡介
注意所有的魔術方法前面都是兩個下劃線__
PHP中的OOP特有的。
比如構造函數和析構函數。
5.2 __tostring()和__invoke()
--定義
__tostring(),當對象被當作String使用時,這個方法會被自動調用;echo $obj;
__invoke(),當對象被當作方法(函數)調用時,這個方法被自動調用;$obj(4);
--栗子
<?php
/*
* tostring()魔術方法
* invoke()魔術方法
*/
class MagicTest{
public function __toString(){
return "This is the class magictest.";
}
public function __invoke($x){
echo "<br/>".$x;
}
}
$obj=new MagicTest();
echo $obj;
$obj(5);
用法和構造函數析構函數類似。比較自動化(自動調用,即使沒有聲明也會調用),但同時比較容易出錯,小心。
5.3 __call()和__callStatic()或重載(overloading)
--定義
當對象訪問不存在的方法名稱時,__call()會被自動調用;
當對象訪問不存在的靜態方法名稱時,__callStatic()會被自動調用;
這兩個方法,又稱為重載(不同於重寫);通過這兩個方法,同一個方法的名稱的調用可以對應不同的方法實現
--栗子
<?php
/*
* tostring()魔術方法
* invoke()魔術方法
*/
class MagicTest{
public function __toString(){
return "This is the class magictest.";
}
public function __invoke($x){
echo "<br/>".$x."<br/>";
}
public function __call($name,$arguments){ //__call的格式是固定的,第一個是方法名,第二個是方法內的參數
echo "Calling ".$name." with parameters: ".implode(",", $arguments)."<br/>";
}
public static function __callstatic($name,$arguments){
echo "Static calling ".$name." with parameters: ".implode(",", $arguments)."<br/>";
}
}
$obj=new MagicTest();
echo $obj;
$obj(5);
$obj->runTest("para1","para2");
$obj::runTest("para3","para4");
注意這裡要求定義方法的時候格式是固定的。
5.4 __get()__set()__isset()__unset
--定義
這幾個方法也被稱為屬性重載的魔術方法。
__set(),在給不可訪問屬性(一種是屬性未定義,另一種是沒有訪問權限,如private)賦值時調用;
__get(),讀取不可訪問屬性的值時調用;
__isset(),當對不可訪問屬性調用isset()或empty()時調用;
__unset(),。。。。。。。。。unset()。。。。。。。。。。
--栗子
<?php
/*
* tostring()魔術方法
* invoke()魔術方法
*/
class MagicTest{
public function __toString(){
return "This is the class magictest.";
}
public function __invoke($x){
echo "<br/>".$x."<br/>";
}
public function __call($name,$arguments){ //__call的格式是固定的,第一個是方法名,第二個是方法內的參數
echo "Calling ".$name." with parameters: ".implode(",", $arguments)."<br/>";
}
public static function __callstatic($name,$arguments){
echo "Static calling ".$name." with parameters: ".implode(",", $arguments)."<br/>";
}
public function __get($name){ //get要有name
return "Getting the property ".$name."<br/>";
}
public function __set($name,$value){ //set要有名有值
echo "Setting the property ".$name." to value ".$value.".<br/>";
}
public function __isset($name){ //判斷是否定義了屬性
echo "__isset invoked<br/>";
return true;
}
public function __unset($name){ //撤銷
echo "unsetting protery ".$name."<br/>";
return true;
}
}
$obj=new MagicTest();
echo $obj;
$obj(5);
$obj->runTest("para1","para2");
$obj::runTest("para3","para4");
echo $obj->classname;
$obj->classname="shit";
echo isset($obj->classname)."<br/>";
unset($obj->classname);echo "<br/>";
echo empty($obj->classname)."<br/>";
結果是
This is the class magictest.
5
Calling runTest with parameters: para1,para2
Static calling runTest with parameters: para3,para4
Getting the property classname
Setting the property classname to value shit.
__isset invoked
1
unsetting protery classname
__isset invoked
可以看到,其實isset和empty調用__isset時一對相反的操作。
然後,__set($name,$value)和__unset($name)是一對相反的操作,但所要元素不一樣;
__isset($name),__get($name)都只需要名字(記住每個魔術方法的作用,理解了,就好記了)。
5.5 __clone()
--定義
就是克隆,或克隆
--栗子
先給出clone關鍵字的用法。
<?php
/*
* 克隆魔術方法
*/
class nbaPlayer{
public $name;
}
$james=new nbaPlayer();
$james->name='James';
echo $james->name."<br/>";
$kobe=clone $james;
$kobe->name='Kobe';
echo $kobe->name;
clone後的,就是個單獨的對象,對其操作不影響原對象。
加上__clone()
<?php
/*
* 克隆魔術方法
*/
class nbaPlayer{
public $name;
public function __clone(){
$this->name="shit";
}
}
$james=new nbaPlayer();
$james->name='James';
echo $james->name."<br/>";
$kobe=clone $james;
echo $kobe->name."<br/>";
$kobe->name='Kobe';
echo $kobe->name."<br/>";
一般來說,用處在於clone後的初始化;或者說,當復制後,不想透露的某些信息的掩蓋。
在工作中常用到這一個,因為常有對某個對象的操作,又不想影響原有數據,就克隆/復制一個出來。
----------------------------------------
2、MySQLi擴展
一、安裝及下載
1.1 優勢及簡介
更新更好,PHP5及以後推薦使用(或者PDO)。
--優點
基於OOP和面向過程的使用;
支持預處理語句;
支持事務。
--其他
速度更快。安全性更好
1.2 安裝及配置
--安裝
配置php,開啟php_mysqli.dll;
配置extension_dir='ext目錄位置';
重啟服務器。
(我用的是WAMP,直接打對勾就行)
--驗證
<?php
/*
* 驗證mysqli是否開啟
*/
//phpinfo();
//2.檢測擴展是否已經加載
var_dump(extension_loaded('mysqli'));
var_dump(extension_loaded('curl'));
echo '<hr/>';
//3.檢測函數是否存在
var_dump(function_exists('mysqli_connect'));
echo '<hr/>';
//4.得到當前已經開啟的擴展
print_r(get_loaded_extensions());
echo '<hr/>';
---
困了,回去洗洗睡覺。。。