2016年11月8日 星期二

PHP中級學習筆記

一、宣告陣列方式

<?php
echo "<pre>";
/*
echo "宣告陣列方式一:索引陣列<br>";
$arr1 = array("張三","李四","老王","千王");
print_r($arr1);
echo "\$arr1[0] = ".$arr1[0]."<br/>";
echo "\$arr1[1] = ".$arr1[1]."<br/>";
echo "\$arr1[2] = ".$arr1[2]."<br/>";
echo "\$arr1[3] = ".$arr1[3]."<br/>";
echo "<hr />";

echo "宣告陣列方式二:關聯陣列<br/>";
$arr2 = array("姓名"=>"張三","年紀"=>15);
print_r($arr2);
echo '$arr2[姓名]='.$arr2['姓名']."<br/>";
echo '$arr2[年紀]='.$arr2['年紀']."<br/>";
echo "<hr />";

echo "宣告陣列方式三:多維陣列<br/>";
$arr3 = array(array("uname"=>"李王","age"=>30),array("uname"=>"大仁","age"=>45));
print_r($arr3);
echo "姓名:".$arr3[1]['uname'].", 年紀:".$arr3[1]['age'];
echo "<hr />";

echo "宣告陣列方式四:指定索引號";
$arr4[0]="A";
$arr4[1]="B";
$arr4[2]="C";
print_r($arr4);
echo "<hr />";

echo "宣告陣列方式五:不指定索引號,由系統指定";
$arr5[]="A";
$arr5[]="B";
$arr5[]="C";
print_r($arr5);
echo "<hr />";

echo "宣告陣列方式六:多維陣列表示法";
$arr6["ENGLISH"]= array();
$arr6["ENGLISH"][]="A";
$arr6["ENGLISH"][]="B";
$arr6["ENGLISH"][]="C";
$arr6["ENGLISH"][]="D";
$arr6["ENGLISH"][]="E";
$arr6["ENGLISH"][]="F";
print_r($arr6);
echo "<hr />";

echo "使用foreach函數輸出一維陣列值<br \>";
$arr7 = array("星期四"=>"上班","星期五"=>"上班","星期六"=>"休息");
foreach ($arr7 as $k=>$value){
echo $k.":".$value."<br/>";
}
echo "<hr />";


echo "使用foreach函數輸串陣列值<br/>";
$arr8["PHP"] = array();
$arr8["PHP"]["cname"] = "PHP基礎課程";
$arr8["PHP"]["ctime"] = "300小時";
$arr8["DVD"] = array();
$arr8["DVD"]["cname"] = "DVD基礎課程";
$arr8["DVD"]["ctime"] = "300小時";
$arr8["HTML"]="HTML基礎課程";
$arr8["javascript"]="javascript基礎課程";
print_r ($arr8);
/*
foreach ($arr8 as  $k => $value){
if (is_array($value)){
echo $k."=".$value['cname'].$value['ctime'];
}else{
echo "<hr />";
echo $k.$value;
}

}*/
$conn = new mysqli("localhost","root","","edu") or die("資料庫連線錯誤");
$conn->query("set names gbk" );
$sql="select * from user";
$result =  $conn->query($sql);
while ($row = $result->fetch_assoc()){
echo "你的姓名是{$row['cname']},年紀為{$row['age']}<br/>";
}

二、類別與對象建立

1、類別語法:
Class 類別名稱 {
 屬性名稱;
 屬性名稱;

  function 方法名稱(){ }
}

2、對象產生的步驟

  • 1.在內存中開避出對象的空 (當建立類別語法時產生)
  • 2.執行構造初始化 (當產生物件時,例如 $this 或 new )
  • 3.對象的引用地址返回 (當2執行完成後,將類別指定給變數產生)


例如:

<?php
class Cars{
public $color;
public $product;
function __construct($c,$p){
$this->color = $c;
$this->product =$p;

}
function Color(){
echo "您的車顏色為:". $this->color."<br/>";

}
function Product(){
echo "你的車型為:". $this->product."<br/>";
}

function ShowCars(){
$this->Color();
$this->Product();
echo "<hr>";
}

}
$car1 = new Cars('red','三菱');
$car1->ShowCars();

$car2 = new Cars('red2','三菱2');
$car2->ShowCars();

?>

補充說明:

3、對象釋放
  • 當整個程式碼執行完成時,PHP自動回收機制
  • 手動執行,使用unset()函數,刪除對象的引用,釋收對象
4、面向對象編程特性
  • 抽象:把一類對象的共同屬性和方法抽象出來,形成類
  • 封裝:把成員方法和成員屬性封裝到類中,穩藏屬性和方法,穩藏方法實現的細節,通過 public protected private final  static 限定類成員的訪問權限,數據被保護在內部,只有通過被授權的成員方法才可以操作,盡可能的對成員進行封裝。
    • public:本類、子類,外部對象都可以調用。
    • protected:只能在本類、子類可以調用,外部對象不可以調用。
    • private:只能本類執行,子類及外部對象都不可調用。
    • final:不能繼承父類或不能重寫父類方法,可運用於方法與類使用。

    • const:類的常量,只該在本類使用,如要引用,則必須使用self::常量名詞。
    • static:需要一個數據對象只服務於類,即類內部可用,對外不可用時,建立對象是極其秏費資源的,因此當一個方法具有比較強的公用性的時候,沒有必要為了調用這個方法而重新再生成該類的實例。定義的方法或變量在程序第一次加載時即駐留內存,於程序結束釋放。
      • 優點與缺點:可以節省內存,因為它是所有對象所公有的,因此,對多個對象來說,靜態數據成員只存儲一處,供所有對象共用。靜態數據成員的值對每個對象都是一樣,但它的值是可以更新的。只要對靜態數據成員的值更新一次,保證所有對象存取更新後的相同的值,這樣可以提高時間效率。失去了多態的特性,不常用的方法定義為static,定義太多增大內存開銷。
      • static變數:通過 static 聲明的成員變量為靜態變量或叫類變量,是該類的公共變量,在第一次使用時即生成,對於該類的所有對象只有一份,是屬於類的,不是屬於對象。可以在任何地方通地類來訪問,是類的全局變量,類創建時即存入內存,呼叫語法
        • self::靜態變量名稱, Ex: slef::$config
        • 類名稱::$config, Ex:modle::$config
      • static 方法: 用 static聲明的方法為靜態方法或叫類方法,執行該方法時不會將對象引用傳給函數,所以我不不能訪問非靜態成員,只能訪問靜態方法或靜態變量。只能使用關於類的方式如 self static parent等。使用時不用生成對象即可執行或也可生成對象做呼叫。
      • static 變數或方法,繼承父類時,子類也會複製一份 static 變數或方法。
<?php
/*
使用靜態方法,實現單一實例範例
*/

class bus{
public $color  ;
static $flag=NULL;
private function __construct(){
echo $this->color = 'blue<br/>';
}
//得到bus資訊
static function getBusInfo(){
if (is_null(self::$flag)){
self::$flag = new bus();
}
return self::$flag;
}
}

$bus1 = bus::getBusInfo();
echo $bus1->color ="red<br/>";
$bus2 =  bus::getBusInfo();
echo $bus2->color ="yellow<br/>";

?>
  • 繼承:可以使一個類繼承併擁有另一個已經存在類的成員屬性和方法,被繼承的類稱為父類或基類,繼承為類為子類,extends 關鍵字 實現繼承關係,PHP繼承是單繼承。
  • 多態性:子類繼承父類,通過對父類成員方法重寫實現多態,但重寫並不是改成父類的成員方法。
  • 重寫:PHP不支援重載,只支援重寫功能。
<?php
/*
實現php重寫功能
*/
//動物的行為屬性
class animal {
function animalRun(){
echo '動物在跑';
}
}
//horse
class horse extends animal {
function animalRun(){
echo "馬在跑";
}
}

//worm
class worm extends animal{
function animalRun(){
echo "蟲在爮";
}
}

//display
class display {
private $obj;
function __construct($type){
$this->obj = new $type();
}
function animalRun(){
$this->obj->animalRun();
}
}

$worm1 = new display('worm');
$worm1->animalRun();
echo "<hr>";
$horse1 = new Display('horse');
$horse1->animalRun();

?>
  • 抽象(abstract) :定義抽象類與方法
    • 使用時機,父類無法確定他子類繼承實際的方法為何,而強制子類必須重寫特定方法時。
    • 類裡有設定抽象方法時,該方法不能有 {},且類也需定義為抽象類,最後繼承的類都必須重寫該方法。
<?php
/*
實現抽象類與抽象方法
*/
abstract class transportation{
public $color='顯示';
function __construct($color){
$this->color = "顏色 {$color} <br/>";
}
abstract function yondo();
}
class car extends transportation{
function yondo(){
echo "四輪前進<br/>";
}
}

class airplane extends transportation{
function yondo(){
echo "在空中飛<br/>";
}
}
$t1 = new car('黃色');
$t1->yondo();
echo $t1->color;
?>


  • 接口 (interface):當所有方法都是抽象時,可使用接口 (interface) 來實現
    • 接口屬性成員,只能是常量成員
    • 接口內只能有抽象方法
    • 接口實現用  implements 關鍵字
    • 可以實現多結口
    • 不可多繼承

<?php
/*
接口(interface) 實現
*/
//usb接口
interface usb{
function connect(); //連結
function quit(); //斷線
}

//插座接口
interface socket{
function plugin();  //插入
function pullout(); //拔出

}
//相機實現
class  camera implements usb,socket {
function connect(){
echo "相機已經連線了,充電中...<br/>";
}

function quit(){
echo "相機已經斷線...<br/>";
}

function plugin(){
echo "手機插頭已插入,充電中...";
}

function pullout(){
echo "手機插頭已插出...";
}
}

//手機實現
class phone implements usb{
function connect(){
echo "手機已經連線了,充電中...<br/>";
}

function quit(){
echo "手機已經斷線...<br/>";
}
}

//由PC執行之實現
class pc{
function usbConnect($usb){
$obj = new $usb();
$obj->connect();
}
function usbQuit($usb){
$obj = new $usb();
$obj->quit();
}
}

class socketPanel{
function pluginConnect($socket){
$obj = new $socket();
$obj->plugin();
}

function pullout2($socket){
$obj = new $socket();
$obj->pullout();
}
}

//執行
$sonyCamera = new pc();
$sonyCamera->usbQuit('camera');
echo "<hr>";
$sonyCamera2 = new socketPanel();
$sonyCamera2->pluginConnect('camera');
?>


5、魔術常量

  • __CLASS__ :取得類名
  • __METHOD__:取的類名與方法名
  • __FUNCTION__:取得函數名
  • __isset():檢查類私有屬性成員,是否存在
  • __unset():刪除類私有屬性成員
  • __wakeup() :當執行反序列化 unserialize(),會檢查類中是否存在 __wakeup(),如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源
  • __sleep():當執行反序列化 serialize(),會檢查類中是否存在如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误
    • Note:
      • __sleep() 不能返回父类的私有成员的名字。这样做会产生一个 E_NOTICE 级别的错误。可以用 Serializable 接口来替代。
      • __sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。
      • __FILE__:取得當前文件(指文件內含__FILE__之文件)之絕對路徑 
  • __DIR__ : 取的當前文件目錄 (PHP 5.3才支援)
  • DIRECTORY_SEPARATOR:取得系統路徑分割符
  • dirname($path):取的當前文件目錄

<?PHP
/*
魔術常量範本
 */
 class car {
function __construct(){
echo __CLASS__."<br />";
echo __METHOD__."<br />";
echo __FUNCTION__."<br />";

}

function display(){
echo __FUNCTION__."<br />";
}
 }
 $c1 = new car();
 $c1->display();

echo "<hr>";
$path = str_replace('\\', '/',dirname(__FILE__));  //取的當前的路徑目錄
@define(WEBDIR,$path);  //網站根目錄
$templatePath = str_replace('\\','/',WEBDIR.DIRECTORY_SEPARATOR.'template'); //取得當前樣版的絕對路徑目錄
@define(TEMPLATE,$templatePath);
echo '網站根目錄:'.WEBDIR.'<br>';
echo '樣版的絕對路徑目錄:'.TEMPLATE.'<br>';

?>

6、其他補充:
$this :
  • 當前對象的屬性與方法引用
  • 如是有繼承,則先找實例化的方法與屬性
  • 當有繼承,本身的類找不到該方法與屬性,則會向上找父類

self:::  :
  • 局限於當前類屬性與方法引用
  • 一般用於靜態屬性與、靜態方法、類常量上
parent::  :使用時機
當子類繼承父類方法,在子類呼叫父類別時

<?php
/*
$this
self::
parent::
的應用

*/
class father{
public  static $role='我是父親';
public  $relationship='父親'."<br/>";
//顯示Role資訊
function showRole(){
return self::$role;
}

//顯示relationship資訊
function showRelationship(){
return $this->relationship;
}
}

class child extends father{
public static $role;
public $relationship='父子'."<br/>";

//顯示Role資訊
function showRole(){
echo parent::$role = '我的角色為父親.'."<br/>" ; //改寫父類別role()屬性的值
echo parent::showRole();   //呼叫父類別show()方法
return self::$role ='我是孩子'."<br/>"; //改寫當前類$role屬性的值
}
//顯示relationship資訊
function showRelationship(){
return $this->relationship;
}


}

$child1 = new child();
echo $child1->showRole();
echo $child1->showRelationship();  //呼叫子類別的showRelationship方法

/*結果:
我的角色為父親.
我的角色為父親.
我是孩子
父子
*/
?>












?>

沒有留言: