PHP
PHP是一種創(chuàng)建動態(tài)交互性站點的服務(wù)器端腳本語言
PHP能夠生成動態(tài)頁面內(nèi)容
PHP能夠創(chuàng)建跳仿、打開开皿、讀取、寫入滋捶、刪除以及關(guān)閉服務(wù)器上的文件
PHP能夠接收表單數(shù)據(jù)
PHP能夠發(fā)送并取回cookies
PHP能夠添加结执、刪除听哭、修改數(shù)據(jù)庫中的數(shù)據(jù)
PHP能夠限制用戶訪問網(wǎng)站中的某些頁面
......
php數(shù)組
- php數(shù)組之索引數(shù)組初始化
PHP有兩種數(shù)組:索引數(shù)組捧书、關(guān)聯(lián)數(shù)組眯杏。
索引和關(guān)聯(lián)兩個詞都是針對數(shù)組的鍵而言的开瞭。
先介紹下索引數(shù)組懒震,索引數(shù)組是指數(shù)組的鍵是整數(shù)的數(shù)組罩息,并且鍵的整數(shù)順序是從0開始,依次類推个扰。
$fruit = array("蘋果","香蕉","菠蘿"); 注意數(shù)組的鍵是從0開始的瓷炮。可以使用
print_r($fruit);語句輸出數(shù)組鍵及對應(yīng)的值递宅。
注1:
數(shù)組初始化喪三種式:1. $fruit=array(); $fruit[0]='香蕉';
2.$fruit=array("xiangjiao"); 3. $fruit=array('0'=>'xiangjiao');
注2:
echo僅能輸出字符串娘香,對于其他變量無能為力。而print_r則是把一個變量的所有人類可閱讀的信息輸出办龄。
例如:print_r可以以數(shù)組為輸入烘绽,而輸出的是人能看懂的數(shù)組結(jié)構(gòu):
$arr = array("1"=>"arr1", "2"=>"arr2", "3"=>"arr3", "4"=>array("4a","4b"));
print_r($arr);
輸出結(jié)果為:
Array ( [1] => arr1 [2] => arr2 [3] => arr3 [4] => Array ( [0] => 4a [1] => 4b ) )
- PHP數(shù)組之索引數(shù)組賦值
索引數(shù)組賦值有三種方式:
1.array[0]='蘋果';
2.$arr=array('0'=>'蘋果');
3.$arr=array('蘋果');
- PHP數(shù)組之訪問索引數(shù)組內(nèi)容
$fruit = array('蘋果','香蕉');
$fruit0 = $fruit['0'];
print_r($fruit0);//結(jié)果為蘋果
- PHP數(shù)組之for循環(huán)訪問索引數(shù)組里的值
$fruit=array('蘋果','香蕉','菠蘿');
for($i=0; $i<3; $i++){
echo '<br>數(shù)組第'.$i.'值是:'.$fruit[$i];
}
注:echo "數(shù)組中的第個{$i}值為$fruit[$i]"."<br>";//這種情況下,必須給變量加大括號@睢0步印!S⑷凇盏檐!
雙引號里用變量 規(guī)范的寫法是加上 {} 或者用 . 來連接。
不加{}的話 可以解析 但是
$bao = "zbx"
echo "我的$bao"驶悟; 可以正常輸出
echo "我的$bao嘿嘿"; 報錯 是因為 不加{}的話 他把“$bao嘿嘿”當(dāng)做一個整體解析成變量了
echo "我的$bao 嘿嘿"; 加個空格就可以出來了
- PHP數(shù)組之foreach循環(huán)訪問索引數(shù)組里的值
$fruit=array('蘋果','香蕉','菠蘿');
foreach($fruit as $k=>$v){
echo '<br>第'.$k.'值是:'.$v;
}
- PHP數(shù)組之關(guān)聯(lián)數(shù)組初始化
關(guān)聯(lián)數(shù)組是指數(shù)組的鍵是字符串的數(shù)組胡野。
$fruit = array(
'apple'=>"蘋果",
'banana'=>"香蕉",
'pineapple'=>"菠蘿"
);
可以使用print_r($fruit);語句輸出數(shù)組鍵及對應(yīng)的值。
- PHP數(shù)組之關(guān)聯(lián)數(shù)組賦值
<?php
//請創(chuàng)建一個數(shù)組變量arr,并嘗試創(chuàng)建一個關(guān)聯(lián)數(shù)組痕鳍,鍵是apple硫豆,值是蘋果
//方法一:
$arr = array();
$arr['apple'] = "蘋果";
//方法二:$arr = array('apple'=>"蘋果");
if( isset($arr) ) {print_r($arr);}
?>
注:isset()檢測變量是否設(shè)置 返回boolean
- PHP數(shù)組之訪問關(guān)聯(lián)數(shù)組內(nèi)容
用數(shù)組變量的名字后跟中括號+鍵的方式來訪問數(shù)組中的值,鍵使用單引號或者雙引號括起來笼呆。
$fruit = array('apple'=>"蘋果",'banana'=>"香蕉",'pineapple'=>"菠蘿");
$fruit0 = $fruit['banana'];
print_r($fruit0);
- PHP數(shù)組之foreach循環(huán)訪問關(guān)聯(lián)數(shù)組里的值
foreach循環(huán)可以將數(shù)組里的所有值都訪問到:
$fruit=array('apple'=>"蘋果",'banana'=>"香蕉",'pineapple'=>"菠蘿");
foreach($fruit as $k=>$v){
echo '<br>水果的英文鍵名:'.$k.'熊响,對應(yīng)的值是:'.$v;
}
類與面向?qū)ο?/h4>
- PHP類和對象
類是面向?qū)ο蟪绦蛟O(shè)計的基本概念,通俗的理解類就是對現(xiàn)實中某一個種類的東西的抽象抄邀, 比如汽車可以
抽象為一個類耘眨,汽車擁有名字、輪胎境肾、速度、重量等屬性胆屿,可以有換擋奥喻、前進、后退等操作方法非迹。
通常定義一個汽車類的方法為:
class Car {
$name = '汽車';
function getName() {
return $this->name;
}
}
類是一類東西的結(jié)構(gòu)描述环鲤,而對象則是一類東西的一個具體實例,例如汽車這個名詞可以理解為汽車的
總類憎兽,但這輛汽車則是一個具體的汽車對象冷离。
對象通過new關(guān)鍵字進行實例化:
$car = new Car();
echo $car->getName();
類與對象看起來比較相似吵冒,但實際上有本質(zhì)的區(qū)別,類是抽象的概念西剥,對象是具體的實例痹栖。類可以使程序
具有可重用性。
例:
<?php
//定義一個類
class Car {
var $name = '汽車';
function getName() {
return $this->name;
}
}
//實例化一個car對象
$car = new Car();
$car->name = '奧迪A6'; //設(shè)置對象的屬性值
echo $car->getName(); //調(diào)用對象的方法 輸出對象的名字
輸出:奧迪A6
- PHP類和對象之創(chuàng)建一個對象
<?php
//定義一個Car類并實例化一個對象
class Car{
public $name ='汽車';
public function run(){
echo '我跑~~~<br />';
}
}
//實例化一個對象
$objcar = new Car();
//調(diào)用該對象的屬性
echo $objcar->name;
//調(diào)用該對象的方法
echo $objcar->run();
- PHP類和對象之類的屬性
1. 在類中定義的變量稱之為屬性瞭空,通常屬性跟數(shù)據(jù)庫中的字段有一定的關(guān)聯(lián)揪阿,因此也可以稱作“字段”。
屬性聲明是由關(guān)鍵字 public咆畏,protected 或者 private 開頭南捂,后面跟一個普通的變量聲明來組成。
屬性的變量可以設(shè)置初始化的默認(rèn)值旧找,默認(rèn)值必須是常量溺健。
2. 默認(rèn)都為public,外部可以訪問钮蛛。一般通過->對象操作符來訪問對象的屬性或者方法鞭缭,對于靜態(tài)屬性
則使用::雙冒號進行訪問。當(dāng)在類成員方法內(nèi)部調(diào)用的時候愿卒,可以使用$this偽變量調(diào)用當(dāng)前對象的屬性缚去。
class Car {
//定義公共屬性
public $name = '汽車';
//定義受保護的屬性
protected $corlor = '白色';
//定義私有屬性
private $price = '100000';
}
$car = new Car();
echo $car->name; //調(diào)用對象的屬性
echo $car->color; //錯誤 受保護的屬性不允許外部調(diào)用
echo $car->price; //錯誤 私有屬性不允許外部調(diào)用
受保護的屬性與私有屬性不允許外部調(diào)用,在類的成員方法內(nèi)部是可以調(diào)用的:
class Car{
private $price = '1000';
public function getPrice() {
return $this->price; //內(nèi)部訪問私有屬性
? }
}
注:帶有 $ 符號的字段被認(rèn)為是變量琼开,而實例化后的對象認(rèn)為是一個變量所以使用 $object 這種形式易结,
而屬性在類中可以看做是一個變量,所以屬性在類中定義的時候需要加上 $ 符柜候,而在對象中搞动,屬性是對象
的一部分,所以使用 $object->value 這種形式區(qū)分渣刷。
- PHP類和對象之定義類的方法
方法就是在類中的function鹦肿,很多時候我們分不清方法與函數(shù)有什么差別,在面向過程的程序設(shè)計中
function叫做函數(shù)辅柴,在面向?qū)ο笾衒unction則被稱之為方法箩溃。
同屬性一樣,類的方法也具有public碌嘀,protected 以及 private 的訪問控制涣旨。
訪問控制的關(guān)鍵字代表的意義為:
public:公開的
protected:受保護的
private:私有的
我們可以這樣定義方法:
class Car {
public function getName() {
return '汽車';
}
?}
$car = new Car();
echo $car->getName();
使用關(guān)鍵字static修飾的,稱之為靜態(tài)方法股冗,靜態(tài)方法不需要實例化對象霹陡,可以通過類名直接調(diào)用,
操作符為雙冒號::。
class Car {
public static function getName() {
return '汽車';
}
?}
echo Car::getName(); //結(jié)果為“汽車”
- PHP類和對象之構(gòu)造函數(shù)和析構(gòu)函數(shù)
PHP5可以在類中使用__construct()定義一個構(gòu)造函數(shù)烹棉,具有構(gòu)造函數(shù)的類攒霹,會在每次對象創(chuàng)建的時候調(diào)用
該函數(shù),因此常用來在對象創(chuàng)建的時候進行一些初始化工作浆洗。
class Car {
function __construct() {
print "構(gòu)造函數(shù)被調(diào)用\n";
}
}
$car = new Car(); //實例化的時候 會自動調(diào)用構(gòu)造函數(shù)__construct催束,這里會輸出一個字符串
在子類中如果定義了__construct則不會調(diào)用父類的__construct,如果需要同時調(diào)用父類的構(gòu)造函數(shù)辅髓,
需要使用parent::__construct()顯式的調(diào)用泣崩。
class Car {
function __construct() {
print "父類構(gòu)造函數(shù)被調(diào)用\n";
}
}
class Truck extends Car {
function __construct() {
print "子類構(gòu)造函數(shù)被調(diào)用\n";
parent::__construct();
}
}
$car = new Truck();
同樣,PHP5支持析構(gòu)函數(shù)洛口,使用__destruct()進行定義矫付,析構(gòu)函數(shù)指的是當(dāng)某個對象的所有引用被刪除,
或者對象被顯式的銷毀時會執(zhí)行的函數(shù)第焰。
class Car {
function __construct() {
print "構(gòu)造函數(shù)被調(diào)用 \n";
}
function __destruct() {
print "析構(gòu)函數(shù)被調(diào)用 \n";
}
}
$car = new Car(); //實例化時會調(diào)用構(gòu)造函數(shù)
echo '使用后买优,準(zhǔn)備銷毀car對象 \n';
unset($car); //銷毀時會調(diào)用析構(gòu)函數(shù)
當(dāng)PHP代碼執(zhí)行完畢以后,會自動回收與銷毀對象挺举,因此一般情況下不需要顯式的去銷毀對象杀赢。
注:構(gòu)造函數(shù)就是:你生下來就開始執(zhí)行(長頭發(fā),張牙齒湘纵,吃飯脂崔,玩)
析構(gòu)函數(shù)就是:你香消玉殞的時候就會執(zhí)行(放進棺材,埋進土里)
- PHP類和對象之Static靜態(tài)關(guān)鍵字
靜態(tài)屬性與方法可以在不實例化類的情況下調(diào)用梧喷,直接使用類名::方法名的方式進行調(diào)用砌左。靜態(tài)屬性不允許
對象使用->操作符調(diào)用。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
}
echo Car::getSpeed(); //調(diào)用靜態(tài)方法
靜態(tài)方法也可以通過變量來進行動態(tài)調(diào)用
$func = 'getSpeed';
$className = 'Car';
echo $className::$func(); //動態(tài)調(diào)用靜態(tài)方法
靜態(tài)方法中铺敌,$this偽變量不允許使用汇歹。可以使用self偿凭,parent产弹,static在內(nèi)部調(diào)用靜態(tài)方法與屬性。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
public static function speedUp() {
return self::$speed+=10;
}
}
class BigCar extends Car {
public static function start() {
parent::speedUp();
}
}
BigCar::start();
echo BigCar::getSpeed();
注:無論是"->"還是"::",可以理解為"的"弯囊。
this :當(dāng)前對象的指針
self:當(dāng)前類的指針痰哨,調(diào)用靜態(tài)方法時
parent:當(dāng)前父類的指針,調(diào)用靜態(tài)方法時
- PHP類和對象之訪問控制
訪問控制通過關(guān)鍵字public匾嘱,protected和private來實現(xiàn)作谭。被定義為公有的類成員可以在任何地方被訪問。
被定義為受保護的類成員則可以被其自身以及其子類和父類訪問奄毡。被定義為私有的類成員則只能被其定義所
在的類訪問。
類屬性必須定義為公有贝或、受保護吼过、私有之一锐秦。為兼容PHP5以前的版本,如果采用 var 定義盗忱,則被視為公有酱床。
class Car {
$speed = 10; //錯誤 屬性必須定義訪問控制
public $name; //定義共有屬性
}
類中的方法可以被定義為公有、私有或受保護趟佃。如果沒有設(shè)置這些關(guān)鍵字扇谣,則該方法默認(rèn)為公有。
class Car {
? //默認(rèn)為共有方法
function turnLeft() {
}
}
如果構(gòu)造函數(shù)定義成了私有方法闲昭,則不允許直接實例化對象了罐寨,這時候一般通過靜態(tài)方法進行實例化,在設(shè)
計模式中會經(jīng)常使用這樣的方法來控制對象的創(chuàng)建序矩,比如單例模式只允許有一個全局唯一的對象鸯绿。
class Car {
private function __construct() {
echo 'object create';
}
private static $_object = null;
public static function getInstance() {
if (empty(self::$_object)) {
self::$_object = new Car(); //內(nèi)部方法可以調(diào)用私有方法,因此這里可以創(chuàng)建對象
}
return self::$_object;
}
}
//$car = new Car(); //這里不允許直接實例化對象
$car = Car::getInstance(); //通過靜態(tài)方法來獲得一個實例
- PHP類和對象之對象繼承
繼承是面向?qū)ο蟪绦蛟O(shè)計中常用的一個特性簸淀,汽車是一個比較大的類瓶蝴,我們也可以稱之為基類,除此之外租幕,
汽車還分為卡車舷手、轎車、東風(fēng)劲绪、寶馬等男窟,因為這些子類具有很多相同的屬性和方法,可以采用繼承汽車類
來共享這些屬性與方法珠叔,實現(xiàn)代碼的復(fù)用蝎宇。
例:
<?php
class Car {
public $speed = 0; //汽車的起始速度是0
public function speedUp() {
$this->speed += 10;
return $this->speed;
}
}
//定義繼承于Car的Truck類
class Truck extends Car {
public function speedUp() {
parent::speedUp();
$this->speed +=50;
return $this->speed;
}
}
$car = new Truck();
$car->speedUp();
echo $car->speed;//輸出60
- PHP類和對象之重載
PHP中的重載指的是動態(tài)的創(chuàng)建屬性與方法,是通過魔術(shù)方法來實現(xiàn)的祷安。屬性的重載通過__set姥芥,__get,
__isset汇鞭,__unset來分別實現(xiàn)對不存在屬性的賦值凉唐、讀取、判斷屬性是否設(shè)置霍骄、銷毀屬性台囱。
class Car {
private $ary = array();
public function __set($key, $val) {
$this->ary[$key] = $val;
}
public function __get($key) {
if (isset($this->ary[$key])) {
return $this->ary[$key];
}
return null;
}
public function __isset($key) {
if (isset($this->ary[$key])) {
return true;
}
return false;
}
public function __unset($key) {
unset($this->ary[$key]);
}
}
$car = new Car();
$car->name = '汽車'; //name屬性動態(tài)創(chuàng)建并賦值
echo $car->name;
方法的重載通過__call來實現(xiàn),當(dāng)調(diào)用不存在的方法的時候读整,將會轉(zhuǎn)為參數(shù)調(diào)用__call方法簿训,當(dāng)調(diào)用不存在
的靜態(tài)方法時會使用__callStatic重載。
class Car {
public $speed = 0;
public function __call($name, $args) {
if ($name == 'speedUp') {
$this->speed += 10;
}
}
}
$car = new Car();
$car->speedUp(); //調(diào)用不存在的方法會使用重載
echo $car->speed;
注:這里的重載不是c++或者java意義上的重載,而是php的一個默認(rèn)函數(shù)__call($name,$args)强品,
當(dāng)你要調(diào)用的函數(shù)不存在時膘侮,函數(shù)名(speedDown)傳給形參$name,里面的參數(shù)傳給形參$args的榛,
然而內(nèi)部具體執(zhí)行需要自己編寫琼了。
- PHP類和對象之對象的高級特性
對象比較,當(dāng)同一個類的兩個實例的所有屬性都相等時夫晌,可以使用比較運算符==進行判斷雕薪,當(dāng)需要判斷
兩個變量是否為同一個對象的引用時,可以使用全等運算符===進行判斷晓淀。
通過$obj2 = clone $obj1;可以將$obj1中的所有屬性都克隆給$obj2所袁,使得兩者的屬性值都相同,
使用$obj2 == $obj1 判斷得true要糊,但他們并不指向同一塊內(nèi)存空間纲熏,所以$obj1 === $obj2 判斷
為false。
通過$obj2 = $obj1;可以使得$obj2和$obj1都指向同一塊內(nèi)存空間锄俄,所以$obj1 == $obj2
和$obj1 === $obj2 判斷都為true局劲。
對象復(fù)制,在一些特殊情況下奶赠,可以通過關(guān)鍵字clone來復(fù)制一個對象鱼填,這時__clone方法會被調(diào)用,
通過這個魔術(shù)方法來設(shè)置屬性的值毅戈。
class Car {
public $name = 'car';
public function __clone() {
$obj = new Car();
$obj->name = $this->name;
}
}
$a = new Car();
$a->name = 'new car';
$b = clone $a;
var_dump($b);
對象序列化苹丸,可以通過serialize方法將對象序列化為字符串,用于存儲或者傳遞數(shù)據(jù)苇经,然后在需要的時候
通過unserialize將字符串反序列化成對象進行使用赘理。
class Car {
public $name = 'car';
}
$a = new Car();
$str = serialize($a); //對象序列化成字符串
echo $str.'<br>';
$b = unserialize($str); //反序列化為對象
var_dump($b);
正則表達式
- 什么叫正則表達式
正則表達式是對字符串進行操作的一種邏輯公式,就是用一些特定的字符組合成一個規(guī)則字符串扇单,稱之
為正則匹配模式商模。
$p = '/apple/';
$str = "apple banna";
if (preg_match($p, $str)) {
echo 'matched';
}
其中字符串'/apple/'就是一個正則表達式,他用來匹配源字符串中是否存在apple字符串蜘澜。
PHP中使用PCRE庫函數(shù)進行正則匹配施流,比如上例中的preg_match用于執(zhí)行一個正則匹配,常用來判斷一類
字符模式是否存在鄙信。
- 正則表達式的基本語法
PCRE庫函數(shù)中瞪醋,正則匹配模式使用分隔符與元字符組成,分隔符可以是非數(shù)字装诡、非反斜線银受、非空格的
任意字符践盼。經(jīng)常使用的分隔符是正斜線(/)、hash符號(#) 以及取反符號(~)蚓土,例如:
/foo bar/
#^[^0-9]$#
~php~
如果模式中包含分隔符宏侍,則分隔符需要使用反斜杠(\)進行轉(zhuǎn)義。
/http:\/\//
如果模式中包含較多的分割字符蜀漆,建議更換其他的字符作為分隔符,也可以采用preg_quote進行轉(zhuǎn)義咱旱。
$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;
分隔符后面可以使用模式修飾符确丢,模式修飾符包括:i, m, s, x等,例如使用i修飾符可以忽略大小寫匹配:
$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
echo '匹配成功';
}
注:
正則表達式中常用的模式修正符有i吐限、g鲜侥、m、s诸典、x描函、e等。它們之間可以組合搭配使用狐粱。
它們的作用如下:
i | 不區(qū)分大小寫
g | 全局匹配
m | 將字符串視為多行舀寓,不管是那行都能匹配
s | 將字符串視為單行,換行符作為普通字符
x | 將模式中的空白忽略
A | 強制從目標(biāo)字符串開頭匹配
D | 如果使用$限制結(jié)尾字符肌蜻,則不允許結(jié)尾有換行
U | 只匹配最近的一個字符串互墓,不重復(fù)匹配
e | 配合函數(shù)preg_replace()使用,可以把匹配來的字符串當(dāng)作正則表達式執(zhí)行
- 元字符與轉(zhuǎn)義
正則表達式中具有特殊含義的字符稱之為元字符蒋搜,常用的元字符有:
\ 一般用于轉(zhuǎn)義字符
^ 斷言目標(biāo)的開始位置(或在多行模式下是行首)
$ 斷言目標(biāo)的結(jié)束位置(或在多行模式下是行尾)
. 匹配除換行符外的任何字符(默認(rèn))
[ 開始字符類定義
] 結(jié)束字符類定義
| 開始一個可選分支
( 子組的開始標(biāo)記
) 子組的結(jié)束標(biāo)記
? 作為量詞棠众,表示 0 次或 1 次匹配冰寻。位于量詞后面用于改變量詞的貪婪特性。 (查閱量詞)
* 量詞,0 次或多次匹配
+ 量詞篱瞎,1 次或多次匹配
{ 自定義量詞開始標(biāo)記
} 自定義量詞結(jié)束標(biāo)記
//下面的\s匹配任意的空白符,包括空格司顿,制表符馅扣,換行符。[^\s]代表非空白符但汞。[^\s]+表示一次或多次
匹配非空白符宿刮。
$p = '/^我[^\s]+(蘋果|香蕉)$/';
$str = "我喜歡吃蘋果";
if (preg_match($p, $str)) {
echo '匹配成功';
}
元字符具有兩種使用場景,一種是可以在任何地方都能使用私蕾,另一種是只能在方括號內(nèi)使用僵缺,在方括號內(nèi)
使用的有:
\ 轉(zhuǎn)義字符
^ 僅在作為第一個字符(方括號內(nèi))時,表明字符類取反
- 標(biāo)記字符范圍
其中^在反括號外面踩叭,表示斷言目標(biāo)的開始位置磕潮,但在方括號內(nèi)部則代表字符類取反翠胰,方括號內(nèi)的減號-可以
標(biāo)記字符范圍,例如0-9表示0到9之間的所有數(shù)字自脯。
//下面的\w匹配字母或數(shù)字或下劃線之景。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的郵箱是Spark.eric@imooc.com";
preg_match($p, $str, $match);
echo $match[0];
- 貪婪模式與懶惰模式
正則表達式中每個元字符匹配一個字符,當(dāng)使用+之后將會變的貪婪膏潮,它將匹配盡可能多的字符锻狗,但使用
問號?字符時,它將盡可能少的匹配字符焕参,既是懶惰模式轻纪。
貪婪模式:在可匹配與可不匹配的時候,優(yōu)先匹配
//下面的\d表示匹配數(shù)字
$p = '/\d+\-\d+/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678
懶惰模式:在可匹配與可不匹配的時候叠纷,優(yōu)先不匹配
$p = '/\d?\-\d?/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:0-1
當(dāng)我們確切的知道所匹配的字符長度的時候刻帚,可以使用{}指定匹配字符數(shù)
$p = '/\d{3}\-\d{8}/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678
注:關(guān)于match數(shù)組的說明:
文檔上的解釋為:如果提供了參數(shù) matches ,它將被填充為搜索結(jié)果涩嚣。 $matches[0] 將包含完整模式
匹配到的文本崇众, $matches[1] 將包含第一個捕獲子組匹配到的文本,以此類推航厚。
文檔上對于子組的說明為:子組通過圓括號分隔界定顷歌,并且它們可以嵌套。
如果正則表達式寫為$p = '/\w+\s\w+/';阶淘,則沒有子組衙吩,$matches[1]為空,而$matches[0]包含所匹配
的文本溪窒;但是將表達式加上括號寫為$p = '/(\w+\s\w+)/';坤塞,則有了子組,此時$matches[1]與
$matches[0]相同澈蚌。
- 使用正則表達式進行匹配
使用正則表達式的目的是為了實現(xiàn)比字符串處理函數(shù)更加靈活的處理方式摹芙,因此跟字符串處理函數(shù)一樣,
其主要用來判斷子字符串是否存在宛瞄、字符串替換浮禾、分割字符串、獲取模式子串等份汗。
PHP使用PCRE庫函數(shù)來進行正則處理盈电,通過設(shè)定好模式,然后調(diào)用相關(guān)的處理函數(shù)來取得匹配結(jié)果杯活。
preg_match用來執(zhí)行一個匹配匆帚,可以簡單的用來判斷模式是否匹配成功,或者取得一個匹配結(jié)果旁钧,他的
返回值是匹配成功的次數(shù)0或者1吸重,在匹配到1次以后就會停止搜索互拾。
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => def )
上面的代碼簡單的執(zhí)行了一個匹配,簡單的判斷def是否能匹配成功嚎幸,但是正則表達式的強大的地方是
進行模式匹配颜矿,因此更多的時候,會使用模式:
$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => abcd [1] => bc )
通過正則表達式可以匹配一個模式嫉晶,得到更多的有用的數(shù)據(jù)骑疆。
- 正則匹配常用案例
正則匹配常用在表單驗證上,一些字段會有一定的格式要求车遂,比如用戶名一般都要求必須是字母封断、數(shù)字
或下劃線組成,郵箱舶担、電話等也都有自己的規(guī)則,因此使用正則表達式可以很好的對這些字段進行驗證:
<?php
$user = array(
'name' => 'spark1985',
'email' => 'spark@imooc.com',
'mobile' => '13312345678'
);
//進行一般性驗證
if (empty($user)) {
die('用戶信息不能為空');
}
if (strlen($user['name']) < 6) {
die('用戶名長度最少為6位');
}
//用戶名必須為字母彬呻、數(shù)字與下劃線
if (!preg_match('/^\w+$/i', $user['name'])) {
die('用戶名不合法');
}
//驗證郵箱格式是否正確
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
die('郵箱不合法');
}
//手機號必須為11位數(shù)字衣陶,且為1開頭
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
die('手機號不合法');
}
echo '用戶信息驗證成功';
會話控制(session與cookie)
- cookie簡介
Cookie是存儲在客戶端瀏覽器中的數(shù)據(jù),我們通過Cookie來跟蹤與存儲用戶數(shù)據(jù)闸氮。一般情況下剪况,
Cookie通過HTTP headers從服務(wù)端返回到客戶端。多數(shù)web程序都支持Cookie的操作蒲跨,因為Cookie是
存在于HTTP的標(biāo)頭之中译断,所以必須在其他信息輸出以前進行設(shè)置,類似于header函數(shù)的使用限制或悲。
PHP通過setcookie函數(shù)進行Cookie的設(shè)置孙咪,任何從瀏覽器發(fā)回的Cookie,PHP都會自動的將他存儲在
$_COOKIE的全局變量之中巡语,因此我們可以通過$_COOKIE['key']的形式來讀取某個Cookie值翎蹈。
PHP中的Cookie具有非常廣泛的使用,經(jīng)常用來存儲用戶的登錄信息男公,購物車等荤堪,且在使用會話Session時
通常使用Cookie來存儲會話id來識別用戶,Cookie具備有效期枢赔,當(dāng)有效期結(jié)束之后澄阳,Cookie會自動的從
客戶端刪除。同時為了進行安全控制踏拜,Cookie還可以設(shè)置域跟路徑碎赢,我們會在稍后的章節(jié)中詳細(xì)的講解他們。
實例:
ob_start();//打開輸出控制緩沖
print_r($_COOKIE);
$content = ob_get_contents();//復(fù)制緩沖區(qū)內(nèi)容到$content中
$content = str_replace(" ", ' ', $content);
ob_clean();//清空(擦掉)輸出緩沖區(qū)
header("content-type:text/html; charset=utf-8");
echo '當(dāng)前的Cookie為:<br/>';
echo nl2br($content);//nl2br 在字符串所有新行之前插入 HTML 換行標(biāo)記
文件系統(tǒng)
- PHP文件系統(tǒng)之判斷文件是否存在
一般情況下在對文件進行操作的時候需要先判斷文件是否存在执隧,PHP中常用來判斷文件存在的函數(shù)有兩個:
is_file與file_exists.
$filename = './test.txt';
if (file_exists($filename)) {
echo file_get_contents($filename);
}
如果只是判斷文件存在揩抡,使用file_exists就行户侥,file_exists不僅可以判斷文件是否存在,同時也可以判斷
目錄是否存在峦嗤,從函數(shù)名可以看出蕊唐,is_file是確切的判斷給定的路徑是否是一個文件。
$filename = './test.txt';
if (is_file($filename)) {
echo file_get_contents($filename);
}
- PHP文件系統(tǒng)之取得文件的修改時間
文件有很多元屬性烁设,包括:文件的所有者替梨、創(chuàng)建時間、修改時間装黑、最后的訪問時間等副瀑。
fileowner:獲得文件的所有者
filectime:獲取文件的創(chuàng)建時間
filemtime:獲取文件的修改時間
fileatime:獲取文件的訪問時間
其中最常用的是文件的修改時間,通過文件的修改時間恋谭,可以判斷文件的時效性糠睡,
經(jīng)常用在靜態(tài)文件或者緩存數(shù)據(jù)的更新。
$mtime = filemtime($filename);
echo '修改時間:'.date('Y-m-d H:i:s', filemtime($filename));
- PHP文件系統(tǒng)之取得文件的大小
通過filesize函數(shù)可以取得文件的大小疚颊,文件大小是以字節(jié)數(shù)表示的狈孔。
$filename = '/data/webroot/usercode/resource/test.txt';
$size = filesize($filename);
如果要轉(zhuǎn)換文件大小的單位,可以自己定義函數(shù)來實現(xiàn)材义。
function getsize($size, $format = 'kb') {
$p = 0;
if ($format == 'kb') {
$p = 1;
} elseif ($format == 'mb') {
$p = 2;
} elseif ($format == 'gb') {
$p = 3;
}
$size /= pow(1024, $p);
return number_format($size, 3);
}
$filename = '/data/webroot/usercode/code/resource/test.txt';
$size = filesize($filename);
$size = getsize($size, 'kb'); //進行單位轉(zhuǎn)換
echo $size.'kb';
值得注意的是均抽,沒法通過簡單的函數(shù)來取得目錄的大小,目錄的大小是該目錄下所有子目錄以及文件大小的總和其掂,
因此需要通過遞歸的方法來循環(huán)計算目錄的大小油挥。
- PHP文件系統(tǒng)之寫入內(nèi)容到文件
與讀取文件對應(yīng),PHP寫文件也具有兩種方式款熬,最簡單的方式是采用file_put_contents深寥。
$filename = './test.txt';
$data = 'test';
file_put_contents($filename, $data);
上例中,$data參數(shù)可以是一個一維數(shù)組华烟,當(dāng)$data是數(shù)組的時候翩迈,會自動的將數(shù)組連接起來,
相當(dāng)于$data=implode('', $data);
同樣的盔夜,PHP也支持類似C語言風(fēng)格的操作方式负饲,采用fwrite進行文件寫入。
$fp = fopen('./test.txt', 'w');
fwrite($fp, 'hello');
fwrite($fp, 'world');
fclose($fp);
- PHP文件系統(tǒng)之刪除文件
跟Unix系統(tǒng)命令類似喂链,PHP使用unlink函數(shù)進行文件刪除返十。
unlink($filename);
刪除文件夾使用rmdir函數(shù),文件夾必須為空椭微,如果不為空或者沒有權(quán)限則會提示失敗洞坑。
rmdir($dir);
如果文件夾中存在文件,可以先循環(huán)刪除目錄中的所有文件蝇率,然后再刪除該目錄迟杂,
循環(huán)刪除可以使用glob函數(shù)遍歷所有文件刽沾。
foreach (glob("*") as $filename) {
unlink($filename);
}
異常處理
- PHP異常處理之拋出一個異常
從PHP5開始,PHP支持異常處理排拷,異常處理是面向?qū)ο笠粋€重要特性侧漓,PHP代碼中的異常通過throw拋出,
異常拋出之后监氢,后面的代碼將不會再被執(zhí)行布蔗。
當(dāng)代碼中使用了try catch的時候,拋出的異常會在catch中捕獲浪腐,否則會直接中斷纵揍。
1、基本語法
try{
//可能出現(xiàn)錯誤或異常的代碼
//catch表示捕獲议街,Exception是php已定義好的異常類
} catch(Exception $e){
//對異常處理泽谨,方法:
//1、自己處理
//2特漩、不處理隔盛,將其再次拋出
}
- PHP異常處理之異常處理類
PHP具有很多異常處理類,其中Exception是所有異常處理的基類拾稳。
Exception具有幾個基本屬性與方法,其中包括了:
message 異常消息內(nèi)容
code 異常代碼
file 拋出異常的文件名
line 拋出異常在該文件的行數(shù)
其中常用的方法有:
getTrace 獲取異常追蹤信息
getTraceAsString 獲取異常追蹤信息的字符串
getMessage 獲取出錯信息
如果必要的話腊脱,可以通過繼承Exception類來建立自定義的異常處理類访得。
//自定義的異常類,繼承了PHP的異成掳迹基類Exception
class MyException extends Exception {
function getInfo() {
return '自定義錯誤信息';
}
}
try {
//使用異常的函數(shù)應(yīng)該位于 "try" 代碼塊內(nèi)悍抑。如果沒有觸發(fā)異常,則代碼將照常繼續(xù)執(zhí)行杜耙。
但是如果異常被觸發(fā)搜骡,會拋出一個異常。
throw new MyException('error');//這里規(guī)定如何觸發(fā)異常佑女。注意:每一個 "throw" 必須對應(yīng)
至少一個 "catch"记靡,當(dāng)然可以對應(yīng)多個"catch"
} catch(Exception $e) {//"catch" 代碼塊會捕獲異常,并創(chuàng)建一個包含異常信息的對象
echo $e->getInfo();//獲取自定義的異常信息
echo $e->getMessage();//獲取繼承自基類的getMessage信息
}
- PHP異常處理之捕獲異常信息
一般的異常處理流程代碼為:
try {
throw new Exception('wrong');
} catch(Exception $ex) {
echo 'Error:'.$ex->getMessage().'<br>';
echo $ex->getTraceAsString().'<br>';
}
echo '異常處理后团驱,繼續(xù)執(zhí)行其他代碼';
數(shù)據(jù)庫操作
- PHP數(shù)據(jù)庫擴展
PHP中一個數(shù)據(jù)庫可能有一個或者多個擴展摸吠,其中既有官方的,也有第三方提供的嚎花。像Mysql常用的擴展有原生
的mysql庫寸痢,也可以使用增強版的mysqli擴展,還可以使用PDO進行連接與操作紊选。
不同的擴展提供基本相近的操作方法啼止,不同的是可能具備一些新特性道逗,以及操作性能可能會有所不同。
mysql擴展進行數(shù)據(jù)庫連接的方法:
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
mysqli擴展:
$link = mysqli_connect('mysql_host', 'mysql_user', 'mysql_password');
PDO擴展
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
- PHP數(shù)據(jù)庫操作之連接MySQL數(shù)據(jù)庫
PHP要對數(shù)據(jù)庫進行操作献烦,首先要做的是與數(shù)據(jù)庫建立連接滓窍,通常我們使用mysql_connect函數(shù)進行數(shù)據(jù)庫連接
該函數(shù)需要指定數(shù)據(jù)庫的地址,用戶名及密碼仿荆。
$host = 'localhost';
$user = 'code1';
$pass = '';
$link = mysql_connect($host, $user, $pass);
PHP連接數(shù)據(jù)庫的方式類似于直接在命令行下通過進行連接贰您,類似:mysql -hlocalhost -ucode1 -p,
當(dāng)連接成功以后拢操,我們需要選擇一個操作的數(shù)據(jù)庫锦亦,通過mysql_select_db函數(shù)來選擇數(shù)據(jù)庫。
mysql_select_db('code1');
通常我們會先設(shè)置一下當(dāng)前連接使用的字符編碼令境,一般的我們會使用utf8編碼杠园。
mysql_query("set names 'utf8'");
通過上面的步驟,我們就與數(shù)據(jù)庫建立了連接舔庶,可以進行數(shù)據(jù)操作了抛蚁。
- PHP數(shù)據(jù)庫操作之執(zhí)行MySQL查詢
在數(shù)據(jù)庫建立連接以后就可以進行查詢,采用mysql_query加sql語句的形式向數(shù)據(jù)庫發(fā)送查詢指令惕橙。
$res = mysql_query('select * from user limit 1');
對于查詢類的語句會返回一個資源句柄(resource)瞧甩,可以通過該資源獲取查詢結(jié)果集中的數(shù)據(jù)。
$row = mysql_fetch_array($res);
var_dump($row);
默認(rèn)的弥鹦,PHP使用最近的數(shù)據(jù)庫連接執(zhí)行查詢肚逸,但如果存在多個連接的情況,
則可以通過參數(shù)指令從那個連接中進行查詢彬坏。
$link1 = mysql_connect('127.0.0.1', 'code1', '');
$link2 = mysql_connect('127.0.0.1', 'code1', '', true); //開啟一個新的連接
$res = mysql_query('select * from user limit 1', $link1); //從第一個連接中查詢數(shù)據(jù)
- PHP數(shù)據(jù)庫操作之插入新數(shù)據(jù)到MySQL中
當(dāng)我們了解了如何使用mysql_query進行數(shù)據(jù)查詢以后朦促,那么類似的,
插入數(shù)據(jù)其實也是通過執(zhí)行一個sql語句來實現(xiàn)栓始,例如:
$sql = "insert into user(name, age, class) values('李四', 18, '高三一班')";
mysql_query($sql); //執(zhí)行插入語句
通常數(shù)據(jù)都是存儲在變量或者數(shù)組中务冕,因此sql語句需要先進行字符串拼接得到。
$name = '李四';
$age = 18;
$class = '高三一班';
$sql = "insert into user(name, age, class) values('$name', '$age', '$class')";
mysql_query($sql); //執(zhí)行插入語句
在mysql中幻赚,執(zhí)行插入語句以后禀忆,可以得到自增的主鍵id,通過PHP的mysql_insert_id函數(shù)可以獲取該id。
$uid = mysql_insert_id();
這個id的作用非常大坯屿,通秤秃可以用來判斷是否插入成功,或者作為關(guān)聯(lián)ID進行其他的數(shù)據(jù)操作领跛。
- PHP數(shù)據(jù)庫操作之取得數(shù)據(jù)查詢結(jié)果
PHP操作數(shù)據(jù)庫跟MySql客戶端上操作極為相似乏德,先進行連接,然后執(zhí)行sql語句,再然后獲取我們想要的結(jié)果集
PHP有多個函數(shù)可以獲取數(shù)據(jù)集中的一行數(shù)據(jù)喊括,最常用的是mysql_fetch_array胧瓜,可以通過設(shè)定參數(shù)來更改
行數(shù)據(jù)的下標(biāo),默認(rèn)的會包含數(shù)字索引的下標(biāo)以及字段名的關(guān)聯(lián)索引下標(biāo)郑什。
$sql = "select * from user limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
可以通過設(shè)定參數(shù)MYSQL_NUM只獲取數(shù)字索引數(shù)組府喳,等同于mysql_fetch_row函數(shù),如果設(shè)定參數(shù)為
MYSQL_ASSOC則只獲取關(guān)聯(lián)索引數(shù)組蘑拯,等同于mysql_fetch_assoc函數(shù)钝满。
$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM); //這兩個方法獲取的數(shù)據(jù)是一樣的
$row = mysql_fetch_assoc($result);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
如果要獲取數(shù)據(jù)集中的所有數(shù)據(jù),我們通過循環(huán)來遍歷整個結(jié)果集申窘。
$data = array();
while ($row = mysql_fetch_array($result)) {
$data[] = $row;
}
- PHP數(shù)據(jù)庫操作之查詢分頁數(shù)據(jù)
我們了解到通過循環(huán)可以獲取一個查詢的所有數(shù)據(jù)弯蚜,在實際應(yīng)用中,我們并不希望一次性獲取數(shù)據(jù)表中的所有
數(shù)據(jù)剃法,那樣性能會非常的低碎捺,因此會使用翻頁功能,每頁僅顯示10條或者20條數(shù)據(jù)贷洲。
通過mysql的limit可以很容易的實現(xiàn)分頁收厨,limit m,n表示從m行后取n行數(shù)據(jù),在PHP中我們需要構(gòu)造m與n
來實現(xiàn)獲取某一頁的所有數(shù)據(jù)优构。
假定當(dāng)前頁為$page诵叁,每頁顯示$n條數(shù)據(jù),那么m為當(dāng)前頁前面所有的數(shù)據(jù)钦椭,既$m = ($page-1) * $n黎休,
在知道了翻頁原理以后,那么我們很容易通過構(gòu)造SQL語句在PHP中實現(xiàn)數(shù)據(jù)翻頁玉凯。
$page = 2;
$n = 2;
$m = ($page - 1) * $n;
$sql = "select * from user limit $m, $n";
$result = mysql_query($sql);
//循環(huán)獲取當(dāng)前頁的數(shù)據(jù)
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[] = $row;
}
在上面的例子中,我們使用了$m與$n變量來表示偏移量與每頁數(shù)據(jù)條數(shù)联贩,但我們推薦使用更有意義的變量名
來表示漫仆,比如$pagesize, $start, $offset等,這樣更容易理解泪幌,有助于團隊協(xié)作開發(fā)盲厌。
- PHP數(shù)據(jù)庫操作之更新與刪除數(shù)據(jù)
數(shù)據(jù)的更新與刪除相對比較簡單,只需要構(gòu)建好相應(yīng)的sql語句祸泪,然后調(diào)用mysql_query執(zhí)行就能完成相應(yīng)的
更新與刪除操作吗浩。
$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
echo '更新成功';
}
同樣的刪除可以使用類似以下的代碼:
$sql = "delete from user where id=2 limit 1";
if (mysql_query($sql)) {
echo '刪除成功';
}
對于刪除與更新操作,可以通過mysql_affected_rows函數(shù)來獲取更新過的數(shù)據(jù)行數(shù)没隘,如果數(shù)據(jù)沒有變化懂扼,
則結(jié)果為0。
$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
echo mysql_affected_rows();
}
- PHP數(shù)據(jù)庫操作之關(guān)閉MySQL連接
當(dāng)數(shù)據(jù)庫操作完成以后,可以使用mysql_close關(guān)閉數(shù)據(jù)庫連接阀湿,默認(rèn)的赶熟,當(dāng)PHP執(zhí)行完畢以后,
會自動的關(guān)閉數(shù)據(jù)庫連接陷嘴。
mysql_close();
雖然PHP會自動關(guān)閉數(shù)據(jù)庫連接映砖,一般情況下已經(jīng)滿足需求,但是在對性能要求比較高的情況下灾挨,
可以在進行完數(shù)據(jù)庫操作之后盡快關(guān)閉數(shù)據(jù)庫連接邑退,以節(jié)省資源,提高性能劳澄。
在存在多個數(shù)據(jù)庫連接的情況下地技,可以設(shè)定連接資源參數(shù)來關(guān)閉指定的數(shù)據(jù)庫連接。
$link = mysql_connect($host, $user, $pass);
mysql_close($link);
類是面向?qū)ο蟪绦蛟O(shè)計的基本概念,通俗的理解類就是對現(xiàn)實中某一個種類的東西的抽象抄邀, 比如汽車可以
抽象為一個類耘眨,汽車擁有名字、輪胎境肾、速度、重量等屬性胆屿,可以有換擋奥喻、前進、后退等操作方法非迹。
通常定義一個汽車類的方法為:
class Car {
$name = '汽車';
function getName() {
return $this->name;
}
}
類是一類東西的結(jié)構(gòu)描述环鲤,而對象則是一類東西的一個具體實例,例如汽車這個名詞可以理解為汽車的
總類憎兽,但這輛汽車則是一個具體的汽車對象冷离。
對象通過new關(guān)鍵字進行實例化:
$car = new Car();
echo $car->getName();
類與對象看起來比較相似吵冒,但實際上有本質(zhì)的區(qū)別,類是抽象的概念西剥,對象是具體的實例痹栖。類可以使程序
具有可重用性。
例:
<?php
//定義一個類
class Car {
var $name = '汽車';
function getName() {
return $this->name;
}
}
//實例化一個car對象
$car = new Car();
$car->name = '奧迪A6'; //設(shè)置對象的屬性值
echo $car->getName(); //調(diào)用對象的方法 輸出對象的名字
輸出:奧迪A6
<?php
//定義一個Car類并實例化一個對象
class Car{
public $name ='汽車';
public function run(){
echo '我跑~~~<br />';
}
}
//實例化一個對象
$objcar = new Car();
//調(diào)用該對象的屬性
echo $objcar->name;
//調(diào)用該對象的方法
echo $objcar->run();
1. 在類中定義的變量稱之為屬性瞭空,通常屬性跟數(shù)據(jù)庫中的字段有一定的關(guān)聯(lián)揪阿,因此也可以稱作“字段”。
屬性聲明是由關(guān)鍵字 public咆畏,protected 或者 private 開頭南捂,后面跟一個普通的變量聲明來組成。
屬性的變量可以設(shè)置初始化的默認(rèn)值旧找,默認(rèn)值必須是常量溺健。
2. 默認(rèn)都為public,外部可以訪問钮蛛。一般通過->對象操作符來訪問對象的屬性或者方法鞭缭,對于靜態(tài)屬性
則使用::雙冒號進行訪問。當(dāng)在類成員方法內(nèi)部調(diào)用的時候愿卒,可以使用$this偽變量調(diào)用當(dāng)前對象的屬性缚去。
class Car {
//定義公共屬性
public $name = '汽車';
//定義受保護的屬性
protected $corlor = '白色';
//定義私有屬性
private $price = '100000';
}
$car = new Car();
echo $car->name; //調(diào)用對象的屬性
echo $car->color; //錯誤 受保護的屬性不允許外部調(diào)用
echo $car->price; //錯誤 私有屬性不允許外部調(diào)用
受保護的屬性與私有屬性不允許外部調(diào)用,在類的成員方法內(nèi)部是可以調(diào)用的:
class Car{
private $price = '1000';
public function getPrice() {
return $this->price; //內(nèi)部訪問私有屬性
? }
}
注:帶有 $ 符號的字段被認(rèn)為是變量琼开,而實例化后的對象認(rèn)為是一個變量所以使用 $object 這種形式易结,
而屬性在類中可以看做是一個變量,所以屬性在類中定義的時候需要加上 $ 符柜候,而在對象中搞动,屬性是對象
的一部分,所以使用 $object->value 這種形式區(qū)分渣刷。
方法就是在類中的function鹦肿,很多時候我們分不清方法與函數(shù)有什么差別,在面向過程的程序設(shè)計中
function叫做函數(shù)辅柴,在面向?qū)ο笾衒unction則被稱之為方法箩溃。
同屬性一樣,類的方法也具有public碌嘀,protected 以及 private 的訪問控制涣旨。
訪問控制的關(guān)鍵字代表的意義為:
public:公開的
protected:受保護的
private:私有的
我們可以這樣定義方法:
class Car {
public function getName() {
return '汽車';
}
?}
$car = new Car();
echo $car->getName();
使用關(guān)鍵字static修飾的,稱之為靜態(tài)方法股冗,靜態(tài)方法不需要實例化對象霹陡,可以通過類名直接調(diào)用,
操作符為雙冒號::。
class Car {
public static function getName() {
return '汽車';
}
?}
echo Car::getName(); //結(jié)果為“汽車”
PHP5可以在類中使用__construct()定義一個構(gòu)造函數(shù)烹棉,具有構(gòu)造函數(shù)的類攒霹,會在每次對象創(chuàng)建的時候調(diào)用
該函數(shù),因此常用來在對象創(chuàng)建的時候進行一些初始化工作浆洗。
class Car {
function __construct() {
print "構(gòu)造函數(shù)被調(diào)用\n";
}
}
$car = new Car(); //實例化的時候 會自動調(diào)用構(gòu)造函數(shù)__construct催束,這里會輸出一個字符串
在子類中如果定義了__construct則不會調(diào)用父類的__construct,如果需要同時調(diào)用父類的構(gòu)造函數(shù)辅髓,
需要使用parent::__construct()顯式的調(diào)用泣崩。
class Car {
function __construct() {
print "父類構(gòu)造函數(shù)被調(diào)用\n";
}
}
class Truck extends Car {
function __construct() {
print "子類構(gòu)造函數(shù)被調(diào)用\n";
parent::__construct();
}
}
$car = new Truck();
同樣,PHP5支持析構(gòu)函數(shù)洛口,使用__destruct()進行定義矫付,析構(gòu)函數(shù)指的是當(dāng)某個對象的所有引用被刪除,
或者對象被顯式的銷毀時會執(zhí)行的函數(shù)第焰。
class Car {
function __construct() {
print "構(gòu)造函數(shù)被調(diào)用 \n";
}
function __destruct() {
print "析構(gòu)函數(shù)被調(diào)用 \n";
}
}
$car = new Car(); //實例化時會調(diào)用構(gòu)造函數(shù)
echo '使用后买优,準(zhǔn)備銷毀car對象 \n';
unset($car); //銷毀時會調(diào)用析構(gòu)函數(shù)
當(dāng)PHP代碼執(zhí)行完畢以后,會自動回收與銷毀對象挺举,因此一般情況下不需要顯式的去銷毀對象杀赢。
注:構(gòu)造函數(shù)就是:你生下來就開始執(zhí)行(長頭發(fā),張牙齒湘纵,吃飯脂崔,玩)
析構(gòu)函數(shù)就是:你香消玉殞的時候就會執(zhí)行(放進棺材,埋進土里)
靜態(tài)屬性與方法可以在不實例化類的情況下調(diào)用梧喷,直接使用類名::方法名的方式進行調(diào)用砌左。靜態(tài)屬性不允許
對象使用->操作符調(diào)用。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
}
echo Car::getSpeed(); //調(diào)用靜態(tài)方法
靜態(tài)方法也可以通過變量來進行動態(tài)調(diào)用
$func = 'getSpeed';
$className = 'Car';
echo $className::$func(); //動態(tài)調(diào)用靜態(tài)方法
靜態(tài)方法中铺敌,$this偽變量不允許使用汇歹。可以使用self偿凭,parent产弹,static在內(nèi)部調(diào)用靜態(tài)方法與屬性。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
public static function speedUp() {
return self::$speed+=10;
}
}
class BigCar extends Car {
public static function start() {
parent::speedUp();
}
}
BigCar::start();
echo BigCar::getSpeed();
注:無論是"->"還是"::",可以理解為"的"弯囊。
this :當(dāng)前對象的指針
self:當(dāng)前類的指針痰哨,調(diào)用靜態(tài)方法時
parent:當(dāng)前父類的指針,調(diào)用靜態(tài)方法時
訪問控制通過關(guān)鍵字public匾嘱,protected和private來實現(xiàn)作谭。被定義為公有的類成員可以在任何地方被訪問。
被定義為受保護的類成員則可以被其自身以及其子類和父類訪問奄毡。被定義為私有的類成員則只能被其定義所
在的類訪問。
類屬性必須定義為公有贝或、受保護吼过、私有之一锐秦。為兼容PHP5以前的版本,如果采用 var 定義盗忱,則被視為公有酱床。
class Car {
$speed = 10; //錯誤 屬性必須定義訪問控制
public $name; //定義共有屬性
}
類中的方法可以被定義為公有、私有或受保護趟佃。如果沒有設(shè)置這些關(guān)鍵字扇谣,則該方法默認(rèn)為公有。
class Car {
? //默認(rèn)為共有方法
function turnLeft() {
}
}
如果構(gòu)造函數(shù)定義成了私有方法闲昭,則不允許直接實例化對象了罐寨,這時候一般通過靜態(tài)方法進行實例化,在設(shè)
計模式中會經(jīng)常使用這樣的方法來控制對象的創(chuàng)建序矩,比如單例模式只允許有一個全局唯一的對象鸯绿。
class Car {
private function __construct() {
echo 'object create';
}
private static $_object = null;
public static function getInstance() {
if (empty(self::$_object)) {
self::$_object = new Car(); //內(nèi)部方法可以調(diào)用私有方法,因此這里可以創(chuàng)建對象
}
return self::$_object;
}
}
//$car = new Car(); //這里不允許直接實例化對象
$car = Car::getInstance(); //通過靜態(tài)方法來獲得一個實例
繼承是面向?qū)ο蟪绦蛟O(shè)計中常用的一個特性簸淀,汽車是一個比較大的類瓶蝴,我們也可以稱之為基類,除此之外租幕,
汽車還分為卡車舷手、轎車、東風(fēng)劲绪、寶馬等男窟,因為這些子類具有很多相同的屬性和方法,可以采用繼承汽車類
來共享這些屬性與方法珠叔,實現(xiàn)代碼的復(fù)用蝎宇。
例:
<?php
class Car {
public $speed = 0; //汽車的起始速度是0
public function speedUp() {
$this->speed += 10;
return $this->speed;
}
}
//定義繼承于Car的Truck類
class Truck extends Car {
public function speedUp() {
parent::speedUp();
$this->speed +=50;
return $this->speed;
}
}
$car = new Truck();
$car->speedUp();
echo $car->speed;//輸出60
PHP中的重載指的是動態(tài)的創(chuàng)建屬性與方法,是通過魔術(shù)方法來實現(xiàn)的祷安。屬性的重載通過__set姥芥,__get,
__isset汇鞭,__unset來分別實現(xiàn)對不存在屬性的賦值凉唐、讀取、判斷屬性是否設(shè)置霍骄、銷毀屬性台囱。
class Car {
private $ary = array();
public function __set($key, $val) {
$this->ary[$key] = $val;
}
public function __get($key) {
if (isset($this->ary[$key])) {
return $this->ary[$key];
}
return null;
}
public function __isset($key) {
if (isset($this->ary[$key])) {
return true;
}
return false;
}
public function __unset($key) {
unset($this->ary[$key]);
}
}
$car = new Car();
$car->name = '汽車'; //name屬性動態(tài)創(chuàng)建并賦值
echo $car->name;
方法的重載通過__call來實現(xiàn),當(dāng)調(diào)用不存在的方法的時候读整,將會轉(zhuǎn)為參數(shù)調(diào)用__call方法簿训,當(dāng)調(diào)用不存在
的靜態(tài)方法時會使用__callStatic重載。
class Car {
public $speed = 0;
public function __call($name, $args) {
if ($name == 'speedUp') {
$this->speed += 10;
}
}
}
$car = new Car();
$car->speedUp(); //調(diào)用不存在的方法會使用重載
echo $car->speed;
注:這里的重載不是c++或者java意義上的重載,而是php的一個默認(rèn)函數(shù)__call($name,$args)强品,
當(dāng)你要調(diào)用的函數(shù)不存在時膘侮,函數(shù)名(speedDown)傳給形參$name,里面的參數(shù)傳給形參$args的榛,
然而內(nèi)部具體執(zhí)行需要自己編寫琼了。
對象比較,當(dāng)同一個類的兩個實例的所有屬性都相等時夫晌,可以使用比較運算符==進行判斷雕薪,當(dāng)需要判斷
兩個變量是否為同一個對象的引用時,可以使用全等運算符===進行判斷晓淀。
通過$obj2 = clone $obj1;可以將$obj1中的所有屬性都克隆給$obj2所袁,使得兩者的屬性值都相同,
使用$obj2 == $obj1 判斷得true要糊,但他們并不指向同一塊內(nèi)存空間纲熏,所以$obj1 === $obj2 判斷
為false。
通過$obj2 = $obj1;可以使得$obj2和$obj1都指向同一塊內(nèi)存空間锄俄,所以$obj1 == $obj2
和$obj1 === $obj2 判斷都為true局劲。
對象復(fù)制,在一些特殊情況下奶赠,可以通過關(guān)鍵字clone來復(fù)制一個對象鱼填,這時__clone方法會被調(diào)用,
通過這個魔術(shù)方法來設(shè)置屬性的值毅戈。
class Car {
public $name = 'car';
public function __clone() {
$obj = new Car();
$obj->name = $this->name;
}
}
$a = new Car();
$a->name = 'new car';
$b = clone $a;
var_dump($b);
對象序列化苹丸,可以通過serialize方法將對象序列化為字符串,用于存儲或者傳遞數(shù)據(jù)苇经,然后在需要的時候
通過unserialize將字符串反序列化成對象進行使用赘理。
class Car {
public $name = 'car';
}
$a = new Car();
$str = serialize($a); //對象序列化成字符串
echo $str.'<br>';
$b = unserialize($str); //反序列化為對象
var_dump($b);
正則表達式是對字符串進行操作的一種邏輯公式,就是用一些特定的字符組合成一個規(guī)則字符串扇单,稱之
為正則匹配模式商模。
$p = '/apple/';
$str = "apple banna";
if (preg_match($p, $str)) {
echo 'matched';
}
其中字符串'/apple/'就是一個正則表達式,他用來匹配源字符串中是否存在apple字符串蜘澜。
PHP中使用PCRE庫函數(shù)進行正則匹配施流,比如上例中的preg_match用于執(zhí)行一個正則匹配,常用來判斷一類
字符模式是否存在鄙信。
PCRE庫函數(shù)中瞪醋,正則匹配模式使用分隔符與元字符組成,分隔符可以是非數(shù)字装诡、非反斜線银受、非空格的
任意字符践盼。經(jīng)常使用的分隔符是正斜線(/)、hash符號(#) 以及取反符號(~)蚓土,例如:
/foo bar/
#^[^0-9]$#
~php~
如果模式中包含分隔符宏侍,則分隔符需要使用反斜杠(\)進行轉(zhuǎn)義。
/http:\/\//
如果模式中包含較多的分割字符蜀漆,建議更換其他的字符作為分隔符,也可以采用preg_quote進行轉(zhuǎn)義咱旱。
$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;
分隔符后面可以使用模式修飾符确丢,模式修飾符包括:i, m, s, x等,例如使用i修飾符可以忽略大小寫匹配:
$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
echo '匹配成功';
}
注:
正則表達式中常用的模式修正符有i吐限、g鲜侥、m、s诸典、x描函、e等。它們之間可以組合搭配使用狐粱。
它們的作用如下:
i | 不區(qū)分大小寫
g | 全局匹配
m | 將字符串視為多行舀寓,不管是那行都能匹配
s | 將字符串視為單行,換行符作為普通字符
x | 將模式中的空白忽略
A | 強制從目標(biāo)字符串開頭匹配
D | 如果使用$限制結(jié)尾字符肌蜻,則不允許結(jié)尾有換行
U | 只匹配最近的一個字符串互墓,不重復(fù)匹配
e | 配合函數(shù)preg_replace()使用,可以把匹配來的字符串當(dāng)作正則表達式執(zhí)行
正則表達式中具有特殊含義的字符稱之為元字符蒋搜,常用的元字符有:
\ 一般用于轉(zhuǎn)義字符
^ 斷言目標(biāo)的開始位置(或在多行模式下是行首)
$ 斷言目標(biāo)的結(jié)束位置(或在多行模式下是行尾)
. 匹配除換行符外的任何字符(默認(rèn))
[ 開始字符類定義
] 結(jié)束字符類定義
| 開始一個可選分支
( 子組的開始標(biāo)記
) 子組的結(jié)束標(biāo)記
? 作為量詞棠众,表示 0 次或 1 次匹配冰寻。位于量詞后面用于改變量詞的貪婪特性。 (查閱量詞)
* 量詞,0 次或多次匹配
+ 量詞篱瞎,1 次或多次匹配
{ 自定義量詞開始標(biāo)記
} 自定義量詞結(jié)束標(biāo)記
//下面的\s匹配任意的空白符,包括空格司顿,制表符馅扣,換行符。[^\s]代表非空白符但汞。[^\s]+表示一次或多次
匹配非空白符宿刮。
$p = '/^我[^\s]+(蘋果|香蕉)$/';
$str = "我喜歡吃蘋果";
if (preg_match($p, $str)) {
echo '匹配成功';
}
元字符具有兩種使用場景,一種是可以在任何地方都能使用私蕾,另一種是只能在方括號內(nèi)使用僵缺,在方括號內(nèi)
使用的有:
\ 轉(zhuǎn)義字符
^ 僅在作為第一個字符(方括號內(nèi))時,表明字符類取反
- 標(biāo)記字符范圍
其中^在反括號外面踩叭,表示斷言目標(biāo)的開始位置磕潮,但在方括號內(nèi)部則代表字符類取反翠胰,方括號內(nèi)的減號-可以
標(biāo)記字符范圍,例如0-9表示0到9之間的所有數(shù)字自脯。
//下面的\w匹配字母或數(shù)字或下劃線之景。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的郵箱是Spark.eric@imooc.com";
preg_match($p, $str, $match);
echo $match[0];
正則表達式中每個元字符匹配一個字符,當(dāng)使用+之后將會變的貪婪膏潮,它將匹配盡可能多的字符锻狗,但使用
問號?字符時,它將盡可能少的匹配字符焕参,既是懶惰模式轻纪。
貪婪模式:在可匹配與可不匹配的時候,優(yōu)先匹配
//下面的\d表示匹配數(shù)字
$p = '/\d+\-\d+/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678
懶惰模式:在可匹配與可不匹配的時候叠纷,優(yōu)先不匹配
$p = '/\d?\-\d?/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:0-1
當(dāng)我們確切的知道所匹配的字符長度的時候刻帚,可以使用{}指定匹配字符數(shù)
$p = '/\d{3}\-\d{8}/';
$str = "我的電話是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //結(jié)果為:010-12345678
注:關(guān)于match數(shù)組的說明:
文檔上的解釋為:如果提供了參數(shù) matches ,它將被填充為搜索結(jié)果涩嚣。 $matches[0] 將包含完整模式
匹配到的文本崇众, $matches[1] 將包含第一個捕獲子組匹配到的文本,以此類推航厚。
文檔上對于子組的說明為:子組通過圓括號分隔界定顷歌,并且它們可以嵌套。
如果正則表達式寫為$p = '/\w+\s\w+/';阶淘,則沒有子組衙吩,$matches[1]為空,而$matches[0]包含所匹配
的文本溪窒;但是將表達式加上括號寫為$p = '/(\w+\s\w+)/';坤塞,則有了子組,此時$matches[1]與
$matches[0]相同澈蚌。
使用正則表達式的目的是為了實現(xiàn)比字符串處理函數(shù)更加靈活的處理方式摹芙,因此跟字符串處理函數(shù)一樣,
其主要用來判斷子字符串是否存在宛瞄、字符串替換浮禾、分割字符串、獲取模式子串等份汗。
PHP使用PCRE庫函數(shù)來進行正則處理盈电,通過設(shè)定好模式,然后調(diào)用相關(guān)的處理函數(shù)來取得匹配結(jié)果杯活。
preg_match用來執(zhí)行一個匹配匆帚,可以簡單的用來判斷模式是否匹配成功,或者取得一個匹配結(jié)果旁钧,他的
返回值是匹配成功的次數(shù)0或者1吸重,在匹配到1次以后就會停止搜索互拾。
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => def )
上面的代碼簡單的執(zhí)行了一個匹配,簡單的判斷def是否能匹配成功嚎幸,但是正則表達式的強大的地方是
進行模式匹配颜矿,因此更多的時候,會使用模式:
$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //結(jié)果為:Array ( [0] => abcd [1] => bc )
通過正則表達式可以匹配一個模式嫉晶,得到更多的有用的數(shù)據(jù)骑疆。
正則匹配常用在表單驗證上,一些字段會有一定的格式要求车遂,比如用戶名一般都要求必須是字母封断、數(shù)字
或下劃線組成,郵箱舶担、電話等也都有自己的規(guī)則,因此使用正則表達式可以很好的對這些字段進行驗證:
<?php
$user = array(
'name' => 'spark1985',
'email' => 'spark@imooc.com',
'mobile' => '13312345678'
);
//進行一般性驗證
if (empty($user)) {
die('用戶信息不能為空');
}
if (strlen($user['name']) < 6) {
die('用戶名長度最少為6位');
}
//用戶名必須為字母彬呻、數(shù)字與下劃線
if (!preg_match('/^\w+$/i', $user['name'])) {
die('用戶名不合法');
}
//驗證郵箱格式是否正確
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
die('郵箱不合法');
}
//手機號必須為11位數(shù)字衣陶,且為1開頭
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
die('手機號不合法');
}
echo '用戶信息驗證成功';
Cookie是存儲在客戶端瀏覽器中的數(shù)據(jù),我們通過Cookie來跟蹤與存儲用戶數(shù)據(jù)闸氮。一般情況下剪况,
Cookie通過HTTP headers從服務(wù)端返回到客戶端。多數(shù)web程序都支持Cookie的操作蒲跨,因為Cookie是
存在于HTTP的標(biāo)頭之中译断,所以必須在其他信息輸出以前進行設(shè)置,類似于header函數(shù)的使用限制或悲。
PHP通過setcookie函數(shù)進行Cookie的設(shè)置孙咪,任何從瀏覽器發(fā)回的Cookie,PHP都會自動的將他存儲在
$_COOKIE的全局變量之中巡语,因此我們可以通過$_COOKIE['key']的形式來讀取某個Cookie值翎蹈。
PHP中的Cookie具有非常廣泛的使用,經(jīng)常用來存儲用戶的登錄信息男公,購物車等荤堪,且在使用會話Session時
通常使用Cookie來存儲會話id來識別用戶,Cookie具備有效期枢赔,當(dāng)有效期結(jié)束之后澄阳,Cookie會自動的從
客戶端刪除。同時為了進行安全控制踏拜,Cookie還可以設(shè)置域跟路徑碎赢,我們會在稍后的章節(jié)中詳細(xì)的講解他們。
實例:
ob_start();//打開輸出控制緩沖
print_r($_COOKIE);
$content = ob_get_contents();//復(fù)制緩沖區(qū)內(nèi)容到$content中
$content = str_replace(" ", ' ', $content);
ob_clean();//清空(擦掉)輸出緩沖區(qū)
header("content-type:text/html; charset=utf-8");
echo '當(dāng)前的Cookie為:<br/>';
echo nl2br($content);//nl2br 在字符串所有新行之前插入 HTML 換行標(biāo)記
一般情況下在對文件進行操作的時候需要先判斷文件是否存在执隧,PHP中常用來判斷文件存在的函數(shù)有兩個:
is_file與file_exists.
$filename = './test.txt';
if (file_exists($filename)) {
echo file_get_contents($filename);
}
如果只是判斷文件存在揩抡,使用file_exists就行户侥,file_exists不僅可以判斷文件是否存在,同時也可以判斷
目錄是否存在峦嗤,從函數(shù)名可以看出蕊唐,is_file是確切的判斷給定的路徑是否是一個文件。
$filename = './test.txt';
if (is_file($filename)) {
echo file_get_contents($filename);
}
文件有很多元屬性烁设,包括:文件的所有者替梨、創(chuàng)建時間、修改時間装黑、最后的訪問時間等副瀑。
fileowner:獲得文件的所有者
filectime:獲取文件的創(chuàng)建時間
filemtime:獲取文件的修改時間
fileatime:獲取文件的訪問時間
其中最常用的是文件的修改時間,通過文件的修改時間恋谭,可以判斷文件的時效性糠睡,
經(jīng)常用在靜態(tài)文件或者緩存數(shù)據(jù)的更新。
$mtime = filemtime($filename);
echo '修改時間:'.date('Y-m-d H:i:s', filemtime($filename));
通過filesize函數(shù)可以取得文件的大小疚颊,文件大小是以字節(jié)數(shù)表示的狈孔。
$filename = '/data/webroot/usercode/resource/test.txt';
$size = filesize($filename);
如果要轉(zhuǎn)換文件大小的單位,可以自己定義函數(shù)來實現(xiàn)材义。
function getsize($size, $format = 'kb') {
$p = 0;
if ($format == 'kb') {
$p = 1;
} elseif ($format == 'mb') {
$p = 2;
} elseif ($format == 'gb') {
$p = 3;
}
$size /= pow(1024, $p);
return number_format($size, 3);
}
$filename = '/data/webroot/usercode/code/resource/test.txt';
$size = filesize($filename);
$size = getsize($size, 'kb'); //進行單位轉(zhuǎn)換
echo $size.'kb';
值得注意的是均抽,沒法通過簡單的函數(shù)來取得目錄的大小,目錄的大小是該目錄下所有子目錄以及文件大小的總和其掂,
因此需要通過遞歸的方法來循環(huán)計算目錄的大小油挥。
與讀取文件對應(yīng),PHP寫文件也具有兩種方式款熬,最簡單的方式是采用file_put_contents深寥。
$filename = './test.txt';
$data = 'test';
file_put_contents($filename, $data);
上例中,$data參數(shù)可以是一個一維數(shù)組华烟,當(dāng)$data是數(shù)組的時候翩迈,會自動的將數(shù)組連接起來,
相當(dāng)于$data=implode('', $data);
同樣的盔夜,PHP也支持類似C語言風(fēng)格的操作方式负饲,采用fwrite進行文件寫入。
$fp = fopen('./test.txt', 'w');
fwrite($fp, 'hello');
fwrite($fp, 'world');
fclose($fp);
跟Unix系統(tǒng)命令類似喂链,PHP使用unlink函數(shù)進行文件刪除返十。
unlink($filename);
刪除文件夾使用rmdir函數(shù),文件夾必須為空椭微,如果不為空或者沒有權(quán)限則會提示失敗洞坑。
rmdir($dir);
如果文件夾中存在文件,可以先循環(huán)刪除目錄中的所有文件蝇率,然后再刪除該目錄迟杂,
循環(huán)刪除可以使用glob函數(shù)遍歷所有文件刽沾。
foreach (glob("*") as $filename) {
unlink($filename);
}
從PHP5開始,PHP支持異常處理排拷,異常處理是面向?qū)ο笠粋€重要特性侧漓,PHP代碼中的異常通過throw拋出,
異常拋出之后监氢,后面的代碼將不會再被執(zhí)行布蔗。
當(dāng)代碼中使用了try catch的時候,拋出的異常會在catch中捕獲浪腐,否則會直接中斷纵揍。
1、基本語法
try{
//可能出現(xiàn)錯誤或異常的代碼
//catch表示捕獲议街,Exception是php已定義好的異常類
} catch(Exception $e){
//對異常處理泽谨,方法:
//1、自己處理
//2特漩、不處理隔盛,將其再次拋出
}
PHP具有很多異常處理類,其中Exception是所有異常處理的基類拾稳。
Exception具有幾個基本屬性與方法,其中包括了:
message 異常消息內(nèi)容
code 異常代碼
file 拋出異常的文件名
line 拋出異常在該文件的行數(shù)
其中常用的方法有:
getTrace 獲取異常追蹤信息
getTraceAsString 獲取異常追蹤信息的字符串
getMessage 獲取出錯信息
如果必要的話腊脱,可以通過繼承Exception類來建立自定義的異常處理類访得。
//自定義的異常類,繼承了PHP的異成掳迹基類Exception
class MyException extends Exception {
function getInfo() {
return '自定義錯誤信息';
}
}
try {
//使用異常的函數(shù)應(yīng)該位于 "try" 代碼塊內(nèi)悍抑。如果沒有觸發(fā)異常,則代碼將照常繼續(xù)執(zhí)行杜耙。
但是如果異常被觸發(fā)搜骡,會拋出一個異常。
throw new MyException('error');//這里規(guī)定如何觸發(fā)異常佑女。注意:每一個 "throw" 必須對應(yīng)
至少一個 "catch"记靡,當(dāng)然可以對應(yīng)多個"catch"
} catch(Exception $e) {//"catch" 代碼塊會捕獲異常,并創(chuàng)建一個包含異常信息的對象
echo $e->getInfo();//獲取自定義的異常信息
echo $e->getMessage();//獲取繼承自基類的getMessage信息
}
一般的異常處理流程代碼為:
try {
throw new Exception('wrong');
} catch(Exception $ex) {
echo 'Error:'.$ex->getMessage().'<br>';
echo $ex->getTraceAsString().'<br>';
}
echo '異常處理后团驱,繼續(xù)執(zhí)行其他代碼';
PHP中一個數(shù)據(jù)庫可能有一個或者多個擴展摸吠,其中既有官方的,也有第三方提供的嚎花。像Mysql常用的擴展有原生
的mysql庫寸痢,也可以使用增強版的mysqli擴展,還可以使用PDO進行連接與操作紊选。
不同的擴展提供基本相近的操作方法啼止,不同的是可能具備一些新特性道逗,以及操作性能可能會有所不同。
mysql擴展進行數(shù)據(jù)庫連接的方法:
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
mysqli擴展:
$link = mysqli_connect('mysql_host', 'mysql_user', 'mysql_password');
PDO擴展
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
PHP要對數(shù)據(jù)庫進行操作献烦,首先要做的是與數(shù)據(jù)庫建立連接滓窍,通常我們使用mysql_connect函數(shù)進行數(shù)據(jù)庫連接
該函數(shù)需要指定數(shù)據(jù)庫的地址,用戶名及密碼仿荆。
$host = 'localhost';
$user = 'code1';
$pass = '';
$link = mysql_connect($host, $user, $pass);
PHP連接數(shù)據(jù)庫的方式類似于直接在命令行下通過進行連接贰您,類似:mysql -hlocalhost -ucode1 -p,
當(dāng)連接成功以后拢操,我們需要選擇一個操作的數(shù)據(jù)庫锦亦,通過mysql_select_db函數(shù)來選擇數(shù)據(jù)庫。
mysql_select_db('code1');
通常我們會先設(shè)置一下當(dāng)前連接使用的字符編碼令境,一般的我們會使用utf8編碼杠园。
mysql_query("set names 'utf8'");
通過上面的步驟,我們就與數(shù)據(jù)庫建立了連接舔庶,可以進行數(shù)據(jù)操作了抛蚁。
在數(shù)據(jù)庫建立連接以后就可以進行查詢,采用mysql_query加sql語句的形式向數(shù)據(jù)庫發(fā)送查詢指令惕橙。
$res = mysql_query('select * from user limit 1');
對于查詢類的語句會返回一個資源句柄(resource)瞧甩,可以通過該資源獲取查詢結(jié)果集中的數(shù)據(jù)。
$row = mysql_fetch_array($res);
var_dump($row);
默認(rèn)的弥鹦,PHP使用最近的數(shù)據(jù)庫連接執(zhí)行查詢肚逸,但如果存在多個連接的情況,
則可以通過參數(shù)指令從那個連接中進行查詢彬坏。
$link1 = mysql_connect('127.0.0.1', 'code1', '');
$link2 = mysql_connect('127.0.0.1', 'code1', '', true); //開啟一個新的連接
$res = mysql_query('select * from user limit 1', $link1); //從第一個連接中查詢數(shù)據(jù)
當(dāng)我們了解了如何使用mysql_query進行數(shù)據(jù)查詢以后朦促,那么類似的,
插入數(shù)據(jù)其實也是通過執(zhí)行一個sql語句來實現(xiàn)栓始,例如:
$sql = "insert into user(name, age, class) values('李四', 18, '高三一班')";
mysql_query($sql); //執(zhí)行插入語句
通常數(shù)據(jù)都是存儲在變量或者數(shù)組中务冕,因此sql語句需要先進行字符串拼接得到。
$name = '李四';
$age = 18;
$class = '高三一班';
$sql = "insert into user(name, age, class) values('$name', '$age', '$class')";
mysql_query($sql); //執(zhí)行插入語句
在mysql中幻赚,執(zhí)行插入語句以后禀忆,可以得到自增的主鍵id,通過PHP的mysql_insert_id函數(shù)可以獲取該id。
$uid = mysql_insert_id();
這個id的作用非常大坯屿,通秤秃可以用來判斷是否插入成功,或者作為關(guān)聯(lián)ID進行其他的數(shù)據(jù)操作领跛。
PHP操作數(shù)據(jù)庫跟MySql客戶端上操作極為相似乏德,先進行連接,然后執(zhí)行sql語句,再然后獲取我們想要的結(jié)果集
PHP有多個函數(shù)可以獲取數(shù)據(jù)集中的一行數(shù)據(jù)喊括,最常用的是mysql_fetch_array胧瓜,可以通過設(shè)定參數(shù)來更改
行數(shù)據(jù)的下標(biāo),默認(rèn)的會包含數(shù)字索引的下標(biāo)以及字段名的關(guān)聯(lián)索引下標(biāo)郑什。
$sql = "select * from user limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
可以通過設(shè)定參數(shù)MYSQL_NUM只獲取數(shù)字索引數(shù)組府喳,等同于mysql_fetch_row函數(shù),如果設(shè)定參數(shù)為
MYSQL_ASSOC則只獲取關(guān)聯(lián)索引數(shù)組蘑拯,等同于mysql_fetch_assoc函數(shù)钝满。
$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM); //這兩個方法獲取的數(shù)據(jù)是一樣的
$row = mysql_fetch_assoc($result);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
如果要獲取數(shù)據(jù)集中的所有數(shù)據(jù),我們通過循環(huán)來遍歷整個結(jié)果集申窘。
$data = array();
while ($row = mysql_fetch_array($result)) {
$data[] = $row;
}
我們了解到通過循環(huán)可以獲取一個查詢的所有數(shù)據(jù)弯蚜,在實際應(yīng)用中,我們并不希望一次性獲取數(shù)據(jù)表中的所有
數(shù)據(jù)剃法,那樣性能會非常的低碎捺,因此會使用翻頁功能,每頁僅顯示10條或者20條數(shù)據(jù)贷洲。
通過mysql的limit可以很容易的實現(xiàn)分頁收厨,limit m,n表示從m行后取n行數(shù)據(jù),在PHP中我們需要構(gòu)造m與n
來實現(xiàn)獲取某一頁的所有數(shù)據(jù)优构。
假定當(dāng)前頁為$page诵叁,每頁顯示$n條數(shù)據(jù),那么m為當(dāng)前頁前面所有的數(shù)據(jù)钦椭,既$m = ($page-1) * $n黎休,
在知道了翻頁原理以后,那么我們很容易通過構(gòu)造SQL語句在PHP中實現(xiàn)數(shù)據(jù)翻頁玉凯。
$page = 2;
$n = 2;
$m = ($page - 1) * $n;
$sql = "select * from user limit $m, $n";
$result = mysql_query($sql);
//循環(huán)獲取當(dāng)前頁的數(shù)據(jù)
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[] = $row;
}
在上面的例子中,我們使用了$m與$n變量來表示偏移量與每頁數(shù)據(jù)條數(shù)联贩,但我們推薦使用更有意義的變量名
來表示漫仆,比如$pagesize, $start, $offset等,這樣更容易理解泪幌,有助于團隊協(xié)作開發(fā)盲厌。
數(shù)據(jù)的更新與刪除相對比較簡單,只需要構(gòu)建好相應(yīng)的sql語句祸泪,然后調(diào)用mysql_query執(zhí)行就能完成相應(yīng)的
更新與刪除操作吗浩。
$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
echo '更新成功';
}
同樣的刪除可以使用類似以下的代碼:
$sql = "delete from user where id=2 limit 1";
if (mysql_query($sql)) {
echo '刪除成功';
}
對于刪除與更新操作,可以通過mysql_affected_rows函數(shù)來獲取更新過的數(shù)據(jù)行數(shù)没隘,如果數(shù)據(jù)沒有變化懂扼,
則結(jié)果為0。
$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
echo mysql_affected_rows();
}
當(dāng)數(shù)據(jù)庫操作完成以后,可以使用mysql_close關(guān)閉數(shù)據(jù)庫連接阀湿,默認(rèn)的赶熟,當(dāng)PHP執(zhí)行完畢以后,
會自動的關(guān)閉數(shù)據(jù)庫連接陷嘴。
mysql_close();
雖然PHP會自動關(guān)閉數(shù)據(jù)庫連接映砖,一般情況下已經(jīng)滿足需求,但是在對性能要求比較高的情況下灾挨,
可以在進行完數(shù)據(jù)庫操作之后盡快關(guān)閉數(shù)據(jù)庫連接邑退,以節(jié)省資源,提高性能劳澄。
在存在多個數(shù)據(jù)庫連接的情況下地技,可以設(shè)定連接資源參數(shù)來關(guān)閉指定的數(shù)據(jù)庫連接。
$link = mysql_connect($host, $user, $pass);
mysql_close($link);