PHP(外文名:PHP: Hypertext Preprocessor,中文名:「超文本預處理器」)是一種通用開源腳本語言。語法吸取了C語言、Java和Perl的特色,利於學習,使用普遍,主要適用於Web開發領域。PHP 獨特的語法混合了C、Java、Perl以及PHP自創的語法。它能夠比CGI或者Perl更快速地執行動態網頁。用PHP作出的動態頁面與其餘的編程語言相比,PHP是將程序嵌入到HTML(標準通用標記語言下的一個應用)文檔中去執行,執行效率比徹底生成HTML標記的CGI要高許多;PHP還能夠執行編譯後代碼,編譯能夠達到加密和優化代碼運行,使代碼運行更快。php
php.exe -f "filename"html
cd C:\wamp\bin\php\php5.5.12 //^在dos中轉義,>新建文件寫一行,>>繼續寫一行 echo ^<?php > test.php echo phpinfo(); >> test.php php.exe -f "test.php"
php.exe -r "php代碼"mysql
php.exe -r "$i = 10; echo $i;"
標準形式linux
# php代碼後沒有其餘內容結束標記有時能夠省略 <?php php代碼 ?> <script language=」php」> php代碼 </script>
短標籤形式(需設置php.ini中short_open_tag = On)正則表達式
<? .....這裏是php代碼 ?>
#可省略 <?php echo 1 ?> #不可省略 <?php echo 1;
<?php $v1 = 1;
<?php $v1 = null; echo isset($v1);
<?php $v1 = null; $v2 = 0; $v3 = 1; echo empty($v1)."==="; echo empty($v2)."==="; echo empty($v3)."===";
將一個變量的數據拷貝一份,而後賦值給另外一個變量。算法
將一個變量的引用拷貝一份,而後賦值給另外一個變量(將另外一個變量指向被引用傳遞變量的數據)。sql
一個變量的名是另外一個變量。數據庫
<?php $v1 = 'v2'; $v2 = 10; echo $$v1;//10
PHP 中的許多預約義變量都是「超全局的」,這意味着它們在一個腳本的所有做用域中均可用。在函數或方法中無需執行 global $variable; 就能夠訪問它們。編程
序列化就是將一個變量的數據轉換爲字符串(並非類型轉換),目的是將該字符串進行存儲和傳輸。
serialize:序列化
unserialize:反序列化
<?php $arr = array('z'=>1,'x'=>2,'c'=>3,'zxc'); var_dump($s = serialize($arr));//序列化 file_put_contents('./test_serialize', $s); var_dump(unserialize(file_get_contents('./test_serialize')));//反序列化
常量是一個簡單值的標識符(名字),在腳本執行期間該值不能改變。
傳統上常量標識符老是大寫的。
<?php define('CONST1', 123); const CONST2 = 456;
<?php define('CONST1', 123); echo CONST1; echo constant('CONST1');//constant(CONST1)->constant('123');
defined()返回布爾值
<?php define('CONST1', 123); echo 'CONST1---'.defined('CONST1'); echo 'CONST2---'.defined('CONST2');
<?php var_dump(PHP_VERSION); var_dump(PHP_OS); var_dump(PHP_EOL); var_dump(M_PI); var_dump(M_PI_2); var_dump(M_1_PI);
名字 | 說明 |
---|---|
__LINE__ | 文件中的當前行號。 |
__FILE__ | 文件的完整路徑和文件名。若是用在被包含文件中,則返回被包含的文件名。 |
__DIR__ | 文件所在的目錄。若是用在被包括文件中,則返回被包括的文件所在的目錄。它等價於 dirname(__FILE__)。除非是根目錄,不然目錄中名不包括末尾的斜槓。 |
__FUNCTION__ | 函數名稱。自 PHP 5起本常量返回該函數被定義時的名字(區分大小寫)。在 PHP 4 中該值老是小寫字母的。 |
__CLASS__ | 類的名稱。自 PHP 5 起本常量返回該類被定義時的名字(區分大小寫)。在 PHP 4 中該值老是小寫字母的。類名包括其被聲明的做用區域(例如 Foo\Bar)。注意自 PHP 5.4 起__CLASS__對 trait 也起做用。當用在 trait 方法中時,__CLASS__是調用 trait 方法的類的名字。 |
__TRAIT__ | Trait 的名字。自 PHP 5.4 起此常量返回 trait 被定義時的名字(區分大小寫)。Trait 名包括其被聲明的做用區域(例如 Foo\Bar)。 |
__METHOD__ | 類的方法名。返回該方法被定義時的名字(區分大小寫)。 |
__NAMESPACE__ | 當前命名空間的名稱(區分大小寫)。此常量是在編譯時定義的。 |
<?php var_dump(__LINE__); var_dump(__FILE__); var_dump(__DIR__); var_dump(__FUNCTION__); var_dump(__CLASS__);//get_class()必須有對象才能得到類名 var_dump(__TRAIT__); var_dump(__METHOD__); var_dump(__NAMESPACE__);
<?php var_dump(decbin(123)); var_dump(bindec('101010'));
應該設置在必定精度要求下比較
<?php $v1 = 1.2/3; echo '$v1='."$v1\r\n"; //0.4==0.4不會打印 if($v1 == 0.4){ echo "$v1==0.4\r\n"; } //設置在0.001的精度下比較 //400==0.4*1000會打印 if(round($v1*1000) == 0.4*1000){ echo ($v1*1000)."==0.4*1000\r\n"; }
<?php var_dump(12345*1000000);
<?php $v1 = 123; echo '$v1\r\n'; echo "---\r\n"; echo "$v1\r\n"; echo "---\r\n"; echo <<<'HTML' 'html1'$v1 HTML;//'html1'$v1 echo "---\r\n"; /* HTML;爲最後一行報錯: Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) */ echo <<<"HTML" "html2"$v1 HTML;//'html1'123 //要有一行
true或false兩個值
隱式轉換爲布爾值是爲false的是:
<?php if($v1){ echo 'yse'; }else{ echo 'no'; }
<?php //使用array定義 $arr1 = array('test1'=>1,'test2'=>2,3,4,5); //使用變量[]定義 $arr2['test1'] = 1; $arr2['test2'] = 2; $arr2[] = 3; $arr2[] = 4; $arr2[] = 5; var_dump($arr1, $arr2); //使用變量[]添加 $arr1[] = 6; var_dump($arr1);
<?php //linux使用[]包圍數組會報錯:Parse error: syntax error, unexpected '[',不知什麼緣由 $array1 = array(1,2,'third'); $array2 = array('one' => 1, 'two' => 2, 'three' => 'third'); $array3 = [1,2,'third'];//儘可能使用 $array4 = ['one' => 1, 'two' => 2, 'three' => 'third'];//儘可能使用 var_dump($array1,$array2,$array3,$array4);
數組指針:
<?php $arr = array(1,2,3,4,5); foreach ($arr as $key => &$value) { echo $value; } var_dump($arr);//最後一項是5 var_dump($value);//5(沒有釋放) foreach ($arr as $key => $value) { echo $value; } var_dump($arr);//最後一項是4 var_dump($value);//4(由於上面的$value引用傳遞了,最後$value一直指向數組最後一個元素) $val = 2; $value = 1;//如今$value仍是指向數組最後一個元素 foreach ($arr as $key => $val) { echo $val; } var_dump($arr);//最後一項是1 var_dump($val);//1(雖然foreach結束但$val不是2,而是最後一項數組最後一項的值1)
<?php $arr = array('test1'=>'test','test2'=>'test',22,33); echo '$value'; foreach($arr as $key => $value){ $arr[] = 'new'; echo $value;//沒有new } echo '&$value'; foreach($arr as $key => &$value){ //每次加上new會循環這個加上的new,進入循環又會加一個new $arr[] = 'new'; echo $value;//有new並死循環 }
<?php $arr = array('test1'=>'test','test2'=>'test',22,33); reset($arr);//數組指針初始化 $len = count($arr); for($i=0;$i<$len;$i++){ $key = key($arr);//key $value = current($arr);//value echo $key,$value; next($arr);//指針移到下一個元素 }
<?php $arr = array('test1'=>'test','test2'=>'test',22,33); var_dump(each($arr));//四個元素0,1,key,value list($v1, $v2) = array('test'=>'test',1=>1,2);//將數字索引對應的值放到list的變量中 var_dump($v1, $v2);//null,1 reset($arr);//數組指針初始化 //當each到數組最後的時候,就返回false,即此時循環結束 while(list($key, $value)=each($arr)){ var_dump($key, $value); }
<?php $arr = array(10,10,5,4,3,6,1,8); $len = count($arr); for($i=0; $i<$len-1; ++$i){ for($j=0; $j<$len-$i-1; ++$j){ ($arr[$j] > $arr[$j+1]) && change($arr[$j], $arr[$j+1]); } } function change(&$v1, &$v2){ $v1 += $v2; $v2 = $v1 - $v2; $v1 -= $v2; } var_dump($arr);
<?php $arr = array(10,10,5,4,3,6,1,8); $len = count($arr); for($i=0; $i<$len-1; ++$i){ $max = 0; for($j=1; $j<$len-$i; ++$j){ ($arr[$j] > $arr[$max]) && $max = $j; } ($max != $len-$i-1) && change($arr[$len-$i-1], $arr[$max]); } function change(&$v1, &$v2){ $v1 += $v2; $v2 = $v1 - $v2; $v1 -= $v2; } var_dump($arr);
<?php class myClass{ public $v1 = 123; public function myfunc(){ echo $this->v1; } } $myobj = new myClass(); echo $myobj->v1; $myobj->myfunc();
資源 resource 是一種特殊變量,保存了到外部資源的一個引用。資源是經過專門的函數來創建和使用的。
因爲資源類型變量保存有爲打開文件、數據庫鏈接、圖形畫布區域等的特殊句柄,所以將其它類型的值轉換爲資源沒有意義。
變量沒有指向任何空間
getType(變量名):獲取一個變量的類型名稱
setType(變量名,目標類型字符串):設置一個變量的類型
is_XX類型()系列函數:判斷某個數據是不是某種類型,包括:
<?php $v1 = 123; echo getType($v1)."---"; echo setType($v1, 'string')."---"; echo is_int($v1)."---"; echo is_string($v1)."---";
經過語法來讓某數據轉換爲另外一種類型的數據
<?php echo (int) 12.3; echo (float) 123;
<?php var_dump((int)"12.3"); var_dump((float)"12.3"); var_dump((int)"12.3a"); var_dump((float)"12.3a"); var_dump((int)"a12.3"); var_dump((float)"a12.3");
+,-,*,/,%(取整後取餘),++,--(前++或--效率高)
字符串++:下一字符
null++:1
false++:沒用
<?php $str1 = "abc"; echo ++$str1."---";//abd $str1 = "張"; echo ++$str1."---";//??? $v1 = null; echo ++$v1."---";//1 $v2 = false; echo ++$v2."---";//沒用仍是false
>,>=,<,<=,==,!=,===,!==
==:數據內容相等
===:數據內容和類型都相等
字符串的比較規則:按字符的前後順序找到第一個不一樣的字符當作整個字符串比較大小
<?php $str123 = "123"; $int123 = 123; $v1 = $str123 == $int123; $v2 = $str123 === $int123; $v3 = "abd" > "abc"; echo "$str123 == $int123 $v1 \r\n"; echo "$str123 === $int123 $v2 \r\n"; echo "'abc' > 'abd' $v3 \r\n";
&&,||,!
邏輯與短路:若是前面是真執行後面的
<?php !defined('BASEPATH') && exit('No direct script access allowed');
邏輯或短路:若是前面是假執行後面的
<?php defined('BASEPATH') || exit('No direct script access allowed');
.,.=
=,+=,-=,*=,/=,%=,.=
數據1 ? 數據2 : 數據3
<?php $is_show = true; echo $is_show ? 'show' : 'hide';
&,|,~,^,<<,>>
<?php $v1 = 1&2; $v2 = 1|2; $v3 = ~1; $v4 = 1^2; $v5 = 1<<1; $v6 = 1>>1; echo "1&1->".$v1.PHP_EOL;//0 echo "1|1->".$v2.PHP_EOL;//3 echo "~1->".$v3.PHP_EOL;//2 echo "1^2->".$v4.PHP_EOL;//3 echo "1<<1->".$v5.PHP_EOL;//2 echo "1>>1->".$v6.PHP_EOL;//0
計算機中的加減法都是:補碼+補碼=補碼(都轉換成補碼運算)
1:開,0:關
eg:PHP的錯誤
值 | 常量 | 說明
---|---|---
1| E_ERROR (integer)| 致命的運行時錯誤。這類錯誤通常是不可恢復的狀況,例如內存分配致使的問題。後果是致使腳本終止再也不繼續運行。
2| E_WARNING (integer)| 運行時警告 (非致命錯誤)。僅給出提示信息,可是腳本不會終止運行。
4| E_PARSE (integer)| 編譯時語法解析錯誤。解析錯誤僅僅由分析器產生。
8| E_NOTICE (integer)| 運行時通知。表示腳本遇到可能會表現爲錯誤的狀況,可是在能夠正常運行的腳本里面也可能會有相似的通知。
16| E_CORE_ERROR (integer)| 在PHP初始化啓動過程當中發生的致命錯誤。該錯誤相似 E_ERROR,可是是由PHP引擎核心產生的。
32| E_CORE_WARNING (integer)| PHP初始化啓動過程當中發生的警告 (非致命錯誤) 。相似 E_WARNING,可是是由PHP引擎核心產生的。
64| E_COMPILE_ERROR (integer)| 致命編譯時錯誤。相似E_ERROR, 可是是由Zend腳本引擎產生的。
128| E_COMPILE_WARNING (integer)| 編譯時警告 (非致命錯誤)。相似 E_WARNING,可是是由Zend腳本引擎產生的。
256| E_USER_ERROR (integer)| 用戶產生的錯誤信息。相似 E_ERROR, 可是是由用戶本身在代碼中使用PHP函數 trigger_error()來產生的。
512| E_USER_WARNING (integer)| 用戶產生的警告信息。相似 E_WARNING, 可是是由用戶本身在代碼中使用PHP函數 trigger_error()來產生的。
1024| E_USER_NOTICE (integer)| 用戶產生的通知信息。相似 E_NOTICE, 可是是由用戶本身在代碼中使用PHP函數 trigger_error()來產生的。
2048| E_STRICT (integer)| 啓用 PHP 對代碼的修改建議,以確保代碼具備最佳的互操做性和向前兼容性。
4096| E_RECOVERABLE_ERROR (integer)| 可被捕捉的致命錯誤。 它表示發生了一個可能很是危險的錯誤,可是尚未致使PHP引擎處於不穩定的狀態。 若是該錯誤沒有被用戶自定義句柄捕獲 (參見 set_error_handler()),將成爲一個 E_ERROR 從而腳本會終止運行。
8192| E_DEPRECATED (integer)| 運行時通知。啓用後將會對在將來版本中可能沒法正常工做的代碼給出警告。
16384| E_USER_DEPRECATED (integer)| 用戶產少的警告信息。 相似 E_DEPRECATED, 可是是由用戶本身在代碼中使用PHP函數 trigger_error()來產生的。
30719| E_ALL (integer)| E_STRICT出外的全部錯誤和警告信息。
<?php echo "NOTICE->".sprintf("%'016s",decbin(E_ERROR)).PHP_EOL;//致命性運行時錯 echo "NOTICE->".sprintf("%'016s",decbin(E_WARNING)).PHP_EOL;//運行時警告 echo "NOTICE->".sprintf("%'016s",decbin(E_PARSE)).PHP_EOL;//編譯時解析錯誤 echo "NOTICE->".sprintf("%'016s",decbin(E_NOTICE)).PHP_EOL;//運行時提醒 echo "STRICT->".sprintf("%'016s",decbin(E_STRICT)).PHP_EOL;//PHP 對代碼的修改建議,以確保代碼具備最佳的互操做性和向前兼容性。 echo "DEPRECATED->".sprintf("%'016s",decbin(E_DEPRECATED)).PHP_EOL;//運行時通知 echo "ALL->".sprintf("%'016s",decbin(E_ALL)).PHP_EOL;//全部的錯誤和警告 //禁用錯誤報告 error_reporting(0); //只顯示運行時錯誤 error_reporting(E_ERROR | E_WARNING | E_PARSE); //只顯示運行時錯誤和異常 error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); // 除了 E_NOTICE,報告其餘全部錯誤(這是在 php.ini 裏的默認設置) error_reporting(E_ALL ^ E_NOTICE); // 報告全部 PHP 錯誤 error_reporting(E_ALL); // 報告全部 PHP 錯誤 error_reporting(-1); ini_set('error_reporting', E_ALL);
+,==,!=(<>),===,!==
+:將右邊的數組項合併到左邊數組的後面,獲得一個新數組。若有重複鍵,則結果以左邊的爲準。
<?php $arr1 = array(1,2,3,4); $arr2 = array(1,4,5,6,7); var_dump($arr1+$arr2);//1,2,3,4,7
==:兩個數組具備相同的鍵名和鍵值則返回true。
===:若是兩個數組具備相同的鍵名和鍵值且順序和類型都同樣。
<?php $arr1 = array(1=>'1',2=>'2',3=>'3',4=>'4'); $arr2 = array(1=>1,2=>2,3=>3,4=>4); $arr3 = array(1=>'1',2=>'2',4=>'4',3=>'3'); var_dump($arr1 == $arr2);//true var_dump($arr1 === $arr2);//false var_dump($arr1 == $arr3);//true var_dump($arr1 === $arr3);//false
@:用於可能發生錯誤的表達式(一般錯誤控制運算符用在程序開發測試階段沒法預測的可能出錯的位置,通常是獲取外部資源的時候)。
<?php $link = @mysqli_connect('localhost','root','error') or die ('can not connect');
<?php //if語句 if(true) echo 1; //if else 語句 if(false) echo 1; else echo 1; //if elseif語句 if(false) echo 1; elseif(true) echo 1; //if elseif else語句 if(false) echo 1; elseif(true) echo 1; else echo 1; //switch //break通常都加上,除非特殊應用 switch (1){ case 1: echo 1; break; case 2: echo 1; break; default: echo 1; }
<?php while(false){ echo 'whilefalse';//不打印 } do{ echo 'dowhilefalse';//打印 }while(false); //不是三個參數是三個表達式 for($v=10;$v<11;++$v){ echo $v;//10 }
break中斷:結束這個循環。
continue中斷:進行下一循環。
能夠加上中斷的層數。(eg:break 2;)
<?php //continue 2; = break;(要有兩重循環) for($v=1;$v<10;++$v){ for($n=1;$n<10;++$n){ if($n>$v){ echo PHP_EOL; break; }else echo "$v*$n=".$v*$n.' '; } } echo PHP_EOL; for($v=1;$v<10;++$v){ for($n=1;$n<10;++$n){ if($n>$v){ echo PHP_EOL; continue 2; }else echo "$v*$n=".$v*$n.' '; } } //continue 2;錯了 echo PHP_EOL; for($n=1;$n<10;++$n){ if($n>3){ echo PHP_EOL; continue 2; }else echo "$n=".$n.' '; }
if ( ... ) : //語句塊 endif; if ( ... ) : //語句塊 else: //語句塊 endif; if ( ... ): //語句塊 elseif( ... ) : //語句塊 elseif( ... ): //語句塊 else: //語句塊 endif; switch( ... ) : case ... case ... endSwitch; while(...): //語句塊 endwhile; for(...; ...; ...): //語句塊 endfor; foreach( ): //語句塊 endForeach;
嚴重不推薦適用!
它可讓咱們的程序執行流程「任意跳轉」。
語法:
goto 標識符1;
...不少語句。
標識符1:
...不少語句。
標識符2:
...不少語句。
goto 標識符2;
注意:
<?php goto a; b: echo 'heyheyhey'.' '; goto c; d: echo 'This is library'.PHP_EOL; a: goto b; c: echo 'Good job'.PHP_EOL; if(rand(0,1)) goto d; else goto a;
終止php腳本的運行:die();或exit();
die是一種「語言結構」,並不是函數,能夠不寫括號。
echo也是一種語言結構,而非函數:
echo (「abc」);
echo 「abc」;
echo 「abc」, 「def」, 123;
<?php echo 'abc'; echo 'abc','def'; echo('abc'); die('123'); die; exit('123'); //echo('abc','def');//錯 //exit '123';//錯 //die '123';//錯
//PHP默認最長執行執行超過30s可能報錯用set_time_limit()解決。 <?php echo "start"; sleep(50); echo "ok";
include,include_once,require,require_once(是語言結構,不是函數)
<?php //./1.php不存在 include('./1.php');//warning require('./1.php');//warning error
dos代碼: cd C:\Users\Administrator\Desktop ::^在dos中轉義,>新建文件寫一行,>>繼續寫一行 echo ^<?php > include_once_test.php echo echo 1; >> include_once_test.php php代碼: <?php include('./include_once_test.php');//加載 include('./include_once_test.php');//加載 include_once('./include_once_test.php');//不加載
dos代碼: cd C:\Users\Administrator\Desktop ::^在dos中轉義,>新建文件寫一行,>>繼續寫一行 echo ^<?php > include_test.php echo echo "php"; >> include_test.php php代碼: <?php echo include('include_test.php')?>//輸出php1 <?php echo include'include_test.php'?>//輸出php1 <?= include('include_test.php')?>//輸出php1 <? include('include_test.php') ?>//輸出php <? include'include_test.php' ?>//輸出php
./ 表示當前網頁文件的所在位置(文件夾,目錄)
../ 表示當前網頁文件的所在位置的上一級位置(文件夾,目錄)
這種相對位置對一個網站中的全部內容(包括php,html,圖片,css,js文件)都有效。
php.ini: ;;;;;;;;;;;;;;;;;;;;;;;;; ; Paths and Directories ; ;;;;;;;;;;;;;;;;;;;;;;;;; ; UNIX: "/path1:/path2" ;include_path = ".:/php/includes" ; ; Windows: "\path1;\path2" ;include_path = ".;c:\php\includes" php腳本中設置: <?php //get_include_path獲取之前的設置別給原有的覆蓋了 $path = get_include_path(); //PATH_SEPARATOR目錄分隔符(unix:":",windows:";") set_include_path($path.PATH_SEPARATOR."c:/dir1"); echo get_include_path();
就像是把include,include_once,require,require_once那一行語句替換成要加載的文件並執行。
注意:在哪裏使用就在哪裏替(eg:在下面的例子中,在函數中調用函數會找不到上層函數的變量)
test.php <?php class TestInclude{ public function func(){ $val = 'func'; $this->inc(); } public function inc(){ // $val = 'inc'; //在test2中var_dump($val);能找到$val = 'inc'; include './test2.php'; } } $ti = new TestInclude(); $ti->inc();//在test2中var_dump($val);找不到$val = 'func'; test2.php <?php var_dump($val);
結束腳本
return;
結束腳本帶返回值(在加載腳本的語句接收)
return 'Hello World'
語法錯誤(程序無法跑),運行時錯誤(跑半道無法跑了),邏輯錯誤(程序正常跑,結果不對)
error, warning,notice什麼的
本身就觸發了
<?php $i = 1/0;//Warning: Division by zero in C:\Users\Administrator\Desktop\test.php
本身根據需求設置的錯誤
<?php $money = 100; if($money < 60) trigger_error("你連終身卡都買不起,這遊戲不適合你。", E_USER_ERROR); elseif($money >= 60 && $money < 10000) trigger_error("先生先買個終身卡,再把648,328,198首衝都買了吧。", E_USER_WARNING); elseif($money >= 10000 && $money < 10000000) trigger_error("只要衝夠錢您就會變得更強。", E_USER_NOTICE); elseif($money >= 10000000) echo "先定一個小目標,衝他一個億。喵";
display_error = On;
ini_set(「display_error」, 1);
error_reporting = E_ALL;
ini_set(「error_reporting」, E_ALL);
在開發階段:咱們一般都是顯示全部錯誤——意圖解決錯誤
在產品階段:咱們一般都是隱藏全部錯誤——並同時將錯誤信息記錄到文件中——錯誤日誌文件
log_errors(是否記錄錯誤日誌),error_log(設定錯誤日誌的文件名,設置爲syslog會放到系統錯誤日誌中)
php.ini中設置錯誤日誌:
log_errors=On//開啓 error_log='php_error.log'//設置文件
腳本中錯誤日誌:
ini_set('log_errors', On);//開啓 ini_set('error_log', 'php_error.log');//設置文件
<?php set_error_handler('myError', E_ALL); echo "$i"; function myError($errNo, $errMsg, $errFile, $errLine){ echo "大事很差了,文件: $errFile 的第 $errLine 行錯了,趕忙去百度吧。".PHP_EOL; echo "錯誤號:$errNo ,$errMsg"; }
形參能夠有默認值(默認值只能是常量表達式,或常量,不能是變量)
形參能夠設置爲引用傳遞
<?php function myFunc($arg1, $arg2){ return $arg1 + $arg2; } function myFunc2($arg1, $arg2 = 1){ return $arg1 + $arg2; } function myFunc3(&$arg1, $arg2){ $arg1 += $arg2; }
<?php //有返回值 function myFunc($arg1, $arg2){ return $arg1 + $arg2; } echo myFunc(1,2); //沒有返回值 function myFunc2($arg1, $arg2){ echo $arg1 + $arg2; } myFunc2(1,2); //引用傳遞 $v1 = 1; function myFunc3(&$arg1, $arg2 = 2){ $arg1 += $arg2; } myFunc3($v1); echo $v1;
實參能夠多於,少於形參。
<?php function myFunc($arg1, $arg2){ echo $arg1 + $arg2; } //多於:捨去多餘的 myFunc(1,2,3,4);//3 //少於:用到時找不到會警告 myFunc(1);//1
定義時能夠不給定形參,調用時能夠給定任意個數的實參。
<?php function myFunc(){ var_dump(func_get_args()); //得到一個函數所接收到的全部實參數據,並結果是一個數組 var_dump(func_get_arg(1)); //得到一個函數所接收到的第n歌實參數據(n從0開始) var_dump(func_num_args()); //得到一個函數所接收到的全部實參數據的個數 } myFunc(1,2,3,4,5);
引用傳遞返回值
<?php function &myFunc(){ static $result = 0;//靜態變量,第一次調用這個函數賦值,再次調用這個函數不會被賦值 return $result; } $v1 = &myFunc();//0 echo $v1; $v1++; $v1 = &myFunc();//1 echo $v1;
函數名是變量
<?php function myFunc($func){ function f1(){ echo "function f1"; } $func(); } myFunc('f1');
<?php $myFunc = function(){ echo "myFunc"; };//這是賦值,這個分號必須有 $myFunc();
<?php $arr = array(1,2,3,4,5,6,7); //求和 $sum = call_user_func_array(function(){ $arr = func_get_args(); $sum = 0; foreach($arr as $v){ $sum += $v; } return $sum; },$arr); echo $sum;
使用:
<?php $global1 = 123; $global2 = 456; function get_global(){ global $global1; echo $global1;//123 echo $GLOBALS['global2'];//456 unset($global1); unset($GLOBALS['global2']); }; get_global(); echo "---".$global1;//123 echo $global2;//undefined
<?php function set_global(){ $GLOBALS['local'] = 'local'; }; set_global(); echo $local; function get_local1(&$v1){ $local = 'local'; $v1 = $local; } get_local1($v1); echo $v1; function &get_local2(){ $local = 'local'; return $local; } $v1 = &get_local2(); echo $v1;
<?php if(function_exists('link_db') == false){ function link_db(){ @mysqli_connect('localhost','123456') or die(mysqli_connect_error()); } } link_db();
求階乘:
<?php function factorial($n){ if($n == 1) return 1; $result = factorial($n-1) * $n; return $result; } echo factorial(10);
求斐波那契數列的第n項的值:
<?php function fibonacci($n){ $last = 1; $result = 1; if($n <= 2){ return 1; } for($i=2;$i<$n;++$i){ $temp = $result; $result += $last; $last = $temp; } return $result; } echo fibonacci(6);
==不推薦使用mysql_XXX()這些方法==
mysqli_query($link, 'CHARSET utf8');
<?php //1. 鏈接數據庫 $link = mysqli_connect('localhost', 'root', '123456'); //2. 設定鏈接編碼 mysqli_set_charset($link, "utf8");//也可使用:mysqli_query($link, "set names utf8"); //3. 選擇數據庫 mysqli_select_db($link, "test");//也可使用:mysqli_query($link, "use test"); //4. 執行sql命令 $result = mysqli_query($link, "show tables"); //5. 處理返回結果 var_dump($result); if($result !== false){ // mysql和mysqli方法不一樣 // 獲取所有結果,並造成二維數組 // mysqli_fetch_array獲取一個結果 $fields = mysqli_fetch_fields($result); while($rec = mysqli_fetch_array($result)){ foreach ($fields as $field) { $field_name = $field->name; $tables[$field_name][] = $rec[$field_name]; } } // 獲取所有結果,沒有字段名 //mysqli_fetch_all獲取所有結果 mysqli_fetch_all($result); }
<?php class PDODB{ private $pdo; function __construct(){ // 1.鏈接數據庫 $dsn = 'mysql:host=127.0.0.1;port=3306;dbname=mysql'; $username = 'root'; $password = '123456'; $driver_options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8' ); $this->pdo = new PDO($dsn, $username, $password, $driver_options); } function show_tables(){ // 2.執行sql語句 $result = $this->pdo->query('select * from user;'); // 3.處理返回結果 # 返回列名和數據的關聯數組 # $list = $result->fetchAll(); # 返回數組,不顯示列名 $list = $result->fetchAll(PDO::FETCH_NUM); var_dump($list); } } $pdo = new PDODB(); $pdo->show_tables();
一條SQL的執行,MySQL分紅兩大步驟:1編譯->2執行
優勢:1.連續執行多條結構相同的SQL速度快(結構已經編譯好了)。2.能夠防止sql注入。
<?php class PDODB{ private $pdo; function __construct(){ $dsn = 'mysql:host=127.0.0.1;port=3306;dbname=test'; $username = 'root'; $password = '123456'; $driver_options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8' ); $this->pdo = new PDO($dsn, $username, $password, $driver_options); } function crate_table_testpre(){ $result = $this->pdo->exec('create table testpre (name varchar(20));'); var_dump($result); } function insert_data(){ $names = array( '張三', '李四', '王五' ); $stmt = $this->pdo->prepare('insert into testpre values (:name)'); foreach ($names as $key => $value) { $stmt->bindValue(':name', $value); $result = $stmt->execute(); var_dump($result); } } } $pdo = new PDODB(); $pdo->crate_table_testpre(); $pdo->insert_data();
PDOStatement對象的經常使用方法
OOP:object oriented program
類:是用於描述「某一些具備共同特徵」的物體的概念,是某一類物體的總稱,包括屬性和方法
對象:是指一個具體的「物體」,該物體隸屬於某個「類別」(類)。一般,對象離不開類,沒有類,就不能有對象。
一個類的內部能夠有3種代碼:屬性,方法和類常量,它們統稱爲「類中成員」。
定義形式:
錯誤定義形式:
$v1 = 1;//不寫做用域
var $v2 = 1+3;//右邊不能是計算表達式
public $v3 = $v2;//右邊不能是變量
使用形式:
$對象->屬性名;//注意:屬性名前面沒有$符號。
<?php class C1{ public $v1 = 10; var $v2 = 10; public $v3; var $v4; } $o1 = new C1(); echo $o1->v1;
定義:跟原來函數定義幾乎同樣。
方法前能夠加修飾詞:public,protected,private,省略就算「public」
方法中的$this是一個「僞對象」,表明當前所屬類的當前對象。
方法中使用self表明當前類名
使用:經過類或類的對象來調用。
<?php class C1{ public $v1 = 123; function f1(){ echo $this->v1; } } $o1 = new C1(); echo $o1->f1();
定義:在定義屬性的時候,前面加上關鍵字static
使用:
<?php class C1{ static $v1 = 123; } $o1 = new C1(); echo C1::$v1; echo $o1::$v1; //echo $o1->$v1;對象沒法這樣使用靜態屬性
定義:在定義方法時前面加上static(靜態方法中不能出現$this,只能使用靜態屬性和靜態方法)
使用:
<?php class C1{ static $v1 = 123; public $v2 = 456; static function f1(){ echo C1::$v1; // echo $this->v2;錯的 // $this->f2();錯的 return new self;//self當前類名 } function f2(){ echo 123; } } $o1 = new C1(); var_dump(C1::f1()); var_dump($o1::f1());
構造方式是類中的一個特殊的方法,其做用是在實例化一個對象的同時,給該對象的屬性賦值,使之一建立完成,就具備了其自己的特有數據(屬性值)。
<?php class C1{ function __construct($v1, $v2){ $this->v1 = $v1; $this->v2 = $v2; } public $v1; public $v2; } $o1 = new C1(123, 456); var_dump($o1->v1); var_dump($o1->v2);
析構方法是「銷燬」對象的時候會自動調用
析構方法一般用於在銷燬對象的時候來「清理數據」
一般,php程序結束後,全部對象都會自動銷燬(其實屬於php內部的垃圾回收機制)
說明:
對象銷燬的幾個情形:
實際上,當一個對象沒有任何一個變量指向它的時候,該對象就會被自動銷燬。若是整個程序結束,也會銷燬。
<?php class C1{ function __construct(){ echo 'construct'.PHP_EOL; } function __destruct(){ echo 'destruct'.PHP_EOL; } } $o1 = new C1();//construct:$o1 $o2 = new C1();//construct:$o2 unset($o1);//construct:$o1 //construct:$o2
建立對象:
<?php class C1{ function f1(){ $o3 = new self; } } $o1 = new C1(); $class1 = 'C1'; $o2 = new $class1(); $o4 = new $o1; // 建立空對象 $o5 = (object)null; // 不經過類建立對象 $o6 = (object)array('name'=>123,'pwd'=>456);
對象的傳值:
默認是值傳遞,可使用引用傳遞
值傳遞:將這個對象複製一個給新變量(對象的屬性和方法不復制,因此這兩個對象共用一套屬性和方法)
引用傳遞:將新變量指向當前對象的空間
<?php class C1{ public $v1 = 10; } $o1 = new C1(); $o2 = $o1; $o3 = &$o1; var_dump($o1);//class C1#1 var_dump($o2);//class C1#1 var_dump($o3);//class C1#1 $o1 = new C1(); var_dump($o1);//class C1#2 var_dump($o2);//class C1#1 var_dump($o3);//class C1#2(引用傳遞)
<?php class C1{ public $test_public = 'test_public'; protected $test_protected = 'test_protected'; private $test_private = 'test_private'; public function func(){ echo $this->test_public;//能夠訪問 echo $this->test_protected;//能夠訪問 echo $this->test_private;//能夠訪問 } } class C2 extends C1{ public function func(){ echo $this->test_public;//能夠訪問 echo $this->test_protected;//能夠訪問 echo $this->test_private;//不能夠訪問 } } $o1 = new C1(); $o2 = new C2(); $o1->func(); $o2->func(); echo $o1->test_public;//能夠訪問 //echo $o1->test_protected;//不能夠訪問 //echo $o1->test_private;//不能夠訪問
parent一般用於在子類中調用父類的成員的時候使用,多數一般就是使用父類的「靜態類」成員。由於parent表明的類,而非對象。
<?php class C1{ public $v; function __construct(){ $this->v = 1; } } class C2 extends C1{ public $v2; function __construct(){ parent::__construct(); $this->v2 = 1; } } $o2 = new C2(); echo $o2->v;//1
重寫就是將從父類繼承下來的屬性或方法從新定義
<?php class C1{ function func1(){ echo 123; } } class C2 extends C1{ //protected function func1(){ // echo 456; //}//會報錯 ////function func1($v1){ // echo 456; //}//會報錯 function func1(){ echo 456; } }
若是某個類不但願對其進行擴展,則能夠將其聲明爲最終類。
<?php final class C1{} class C2 extends C1{}//會報錯Class C2 may not inherit from final class (C1)
若是某個方法不但願被下級類覆蓋,就能夠對其聲明爲最終方法。
<?php class C1{ final function final_func(){ } } class C2 extends C1{ function final_func(){ }//會報錯Cannot override final method C1::final_func() }
在正常定義類的前面,加上關鍵字:abstract,那就構成抽象類。
抽象類能夠用來規範一些類的共同特性,但又不須要去對其進行實例化。
抽象方法是一個沒有方法體(也不含大括號)的方法。
方法前面須要加上abstract。
<?php abstract class Animal{ public $legs = 4; public $eyes = 2; public abstract function run(); } class Man extends Animal{ public $legs = 2; public function run(){ echo "man can run with 6 meters per second"; } } class Dog extends Animal{ public function run(){ echo "man can run with 20 meters per second"; } }
其基本語法是這樣的:
在一個類中,有多個同名的方法,每一個方法的參數不一樣而已。這種現象就稱爲「重載」。
參數不一樣能夠是:數量個數不一樣,或類型不一樣,或順序不一樣。
好比:
class A{ int function f1(int x){...} int function f1(int x, int y){...} int function f1(string s, int m){...}
但,在php中,一個類中,根本就不能夠定義多個同名方法——這直接是語法錯誤。
實際上,php中的重載指的是:
屬性重載:若是使用一個不存在的屬性,就會去自動調用類中預先定義好的某個方法以處理數據
方法重載:若是使用一個不存在的方法,就會去自動調用類中預先定義好的某個方法以處理該行爲
屬性有4種使用情形:
所謂屬性重載,就是在面對上述4種情形的屬性使用場景中,該對象若是來「應對」的問題。
若是某屬性不存在,但在語法中使用以下情形,則會發生
<?php class C1{ public $v1 = 1; public $propArr = array(); function __get($propName){ if(isset($this->propArr[$propName])){ return $this->propArr[$propName]; } return "不存在的屬性 $propName"; } function __set($propName,$value){ $this->propArr[$propName] = $value; } function __isset($propName){ if(isset($this->propArr[$propName])){ return true; } return false; } function __unset($propName){ unset($this->propArr[$propName]); } } $obj = new C1(); $obj->v2 = 123; echo $obj->v2;//123 echo isset($obj->v2);//1 unset($obj->v2);
當使用一個對象調用一個不存在的普通方法的時候,會自動去調用預先定義好的「__call」方法。
<?php class C1{ function f1(){ echo 'f1'; } function f2($v){ echo "f2 $v"; } function __call($name, $array){ $count = count($array); if($count == 0){ $this->f1(); }elseif($count == 1){ $this->f2($array[0]); } } } $obj = new C1(); $obj->ff(); $obj->ff("123");
接口中只有兩類最簡單特性信息:(沒有普通方法)
接口能夠看做是抽象類的更高層面的抽象規範,不考慮接口常量的話,那麼就至關於之規定了下級類要作什麼,至於怎麼就,沒有規定。
接口能夠實現「多繼承」(多實現),而類不行。
一個類只能繼承一個父類,但能夠實現多個「上級接口」,語法形式:
class 類A extends 類B implements 接口1,接口2,... {...}
一個接口一樣能夠繼承另外一個接口(也是單繼承):
interface 接口1 extends 接口2{...}
<?php interface I1{ const V1 = 1; function f1(); } interface I2 extends I1{ const V2 = 2; function f2(); } class C1 implements I1,I2{ public function __construct(){ echo self::V1; echo self::V2; } function f1(){} function f2(){} } $o1 = new C1();
作法1:使用__autoload魔術函數
<?php function testFile(){ mkdir("C:/Users/Administrator/library"); $file = fopen("C:/Users/Administrator/library/A.class.php", 'w'); fwrite($file, "<?php\n"); fwrite($file, "class A{}"); fclose($file); } function __autoload($className){ require "C:/Users/Administrator/library/{$className}.class.php"; } testFile(); $obj = new A(); var_dump($obj);
作法2:使用spl_autoload_register函數
用spl_autoload_register函數能夠聲明多個能夠用來代替__autoload函數做用的函數(類文件分佈在不一樣的目錄中可使用這種方法)
<?php function testFile(){ mkdir("C:/Users/Administrator/library"); $file = fopen("C:/Users/Administrator/library/A.class.php", 'w'); fwrite($file, "<?php\n"); fwrite($file, "class A{}"); fclose($file); } spl_autoload_register('autoload1'); spl_autoload_register('autoload2'); function autoload1($className){ require "C:/Users/Administrator/library/{$className}.class.php"; } function autoload2($className){ require "C:/Users/Administrator/class/{$className}.class.php"; } testFile(); /* 1.先看這個文件中是否加載該類 2.autoload1運行後是否加載該類 3.autoload2運行後是否加載該類 */ $obj = new A(); var_dump($obj);
淺克隆(默認):只能克隆對象中的「非對象非資源」數據
<?php class C1{public $v1 = 1;} class C2{ public $v2 = 2; public $v3; public function __construct(){ $this->v3 = new C1(); } } var_dump($o1 = new C2()); var_dump($o2 = clone $o1);//共用一個v3
深克隆:要想實現深克隆(一個對象的全部屬性數據都完全實現了「複製」),就須要對該對象類使用魔術方法__clone(),人爲去複製淺克隆複製不了數據。
<?php class C1{public $v1 = 1;} class C2{ public $v2 = 2; public $v3; public function __construct(){ $this->v3 = new C1(); } public function __clone(){ $this->v3 = clone $this->v3; } } var_dump($o1 = new C2()); var_dump($o2 = clone $o1);//新建了個v3
用foreach語句進行遍歷(只能遍歷可訪問的屬性)
<?php class C1{ public $v1 = 1; protected $v2 = 2; private $v3 = 3; public function fetchAllProp(){ foreach($this as $key => $value){ echo "$key => $value".PHP_EOL; } } } $o1 = new C1(); //只有1 foreach($o1 as $key => $value){ echo "$key => $value".PHP_EOL; } echo "---".PHP_EOL; //有1,2,3 $o1->fetchAllProp();
stdclass:該類內部沒有定義任何屬性,但咱們仍是可使用該類的屬性(不存在的屬性)
<?php var_dump($obj = new stdclass()); $obj->v1 = 1; $obj->v2 = 2; var_dump($obj);
<?php var_dump($o_arr = (object) array("v1" => 1,"v2"=>2,3,4)); var_dump($n_arr = (object) null); var_dump($n_arr = (object) 1);
php是弱類型語言,其特色是無需爲變量指定類型,並且在其後也能夠存儲任何類型。
但在php的較新的語法中,在某些特定場合,針對某些特定類型,也能夠進行語法約束。
特定場合:函數(或方法)的形參變量
特定類型:對象類型(類名),接口類型(接口名),數組類型(array),函數類型(callable)
<?php class C1{} interface I1{} class C2 implements I1{} function f1(C1 $v){//只能傳該類的對象 var_dump($v); } function f2(I1 $v){//只能傳實現該接口的類的對象 var_dump($v); } function f3(array $v){//只能傳數組 var_dump($v); } function f4(callable $v){//只能傳函數 var_dump($v); }
當對一個對象進行「序列化」操做的時候,會自動調用類中的__sleep()方法;
當「反序列化」一個對象的時候,會自動調用對應類中的__wakeup()方法;
<?php class C1{ public $v1 = 1; public $v2 = 2; function __sleep(){//只保存C1 echo "__sleep"; return array('v1'); } function __wakeup(){//常常用於從新創建數據庫鏈接,或執行其它初始化操做。 echo "__wakeup"; } } var_dump($s = serialize(new C1)); file_put_contents('./test_serialize', $s); var_dump(unserialize(file_get_contents('./test_serialize')));
<?php class C1{ public $v1 = 1; public $v2 = 2; function __tostring(){ return "{$this->v1},{$this->v2}"; } } var_dump((string)new C1());
<?php class C1{ public $v1 = 1; public $v2 = 2; function __invoke(){ echo "你怎麼能夠拿對象當函數,好討厭,錘你胸口"; } } $obj = new C1(); $obj();//打印:你怎麼能夠拿對象當函數,好討厭,錘你胸口
系統函數
運算符
<?php class C1{} class C2 extends C1{} $obj1 = new C1(); $obj2 = new C2(); var_dump($obj1 instanceof C1);//true var_dump($obj2 instanceof C1);//true
當一個對象調用一個實例方法,而後,在該實例方法中又去「靜態」調用另外一個類的普通方法,則在類的普通方法中會自動得到在實例方法中的那個$this對象。
<?php class C1{ public $v1 = 1; function f1(){ @C2::f2(); @C2::f3(); } } class C2{ function f2(){ var_dump($this);//有this } static function f3(){ var_dump($this);//null } } $o1 = new C1(); $o1->f1();
static在類方法中表明調用該方法的對象所在的類
<?php class C1{ public static $v = 1; function f1(){ echo self::$v; echo static::$v; } } class C2 extends C1{ public static $v = 2; } $o1 = new C1(); $o2 = new C2(); $o1->f1();//11 echo "---"; $o2->f1();//1,2
可見static有3個不一樣含義的語法:
function f1(){ static $v1 = 1; }
class A{ static $v1 = 1; static function f1(){} }
class A{ function f1(){ static::f2();//static此時指代調用f1這個方法的類(或對象的類) self::f2(); //self這裏永遠指代當前A這個類。 } }
設計模式就是一些解決問題的「常規作法」,是一種認爲較好的經驗總結。面對不一樣的問題,可能會有不一樣的解決辦法,此時就能夠稱爲不一樣的設計模式。
在實際應用中,遇到須要去實例化不少不少的類以獲得對象的狀況,能夠設計出一個工廠(類),該工廠(類)的做用就是實例化各類對象。這種工廠一般只要指定類名,就能夠據此獲取一個該類的對象。
<?php class factory{ static function testFile(){ mkdir("C:/Users/Administrator/class"); $file = fopen("C:/Users/Administrator/class/A.class.php", 'w'); fwrite($file, "<?php\n"); fwrite($file, "class A{}"); fclose($file); } static function getInstance($className){ if(file_exists("C:/Users/Administrator/class/{$className}.class.php")){ require_once "C:/Users/Administrator/class/{$className}.class.php"; return $obj1 = new $className(); }else{ return null; } } } factory::testFile(); $o1 = factory::getInstance("A"); var_dump($o1);
在實際應用中,對於某些類在使用它的時候,從程序運行的開始到結束都只須要一個對象就能夠完成全部任務。就可使用單例。
單例:某個類,只容許其建立出一個對象,即便去進行屢次建立,也只能獲得一個對象。
<?php class DB{ public $db = 'mysql'; private static $instance; //禁止經過構造方法建立對象(new對象) private function __construct(){} //禁止經過克隆對象(克隆產生的對象也是新對象) private function __clone(){} public static function getNew(){ if( !isset(DB::$instance)){ DB::$instance = new self; } return DB::$instance; } } $db1 = DB::getNew(); $db1->db = 'mysql1'; $db2 = DB::getNew(); echo $db2->db;//mysql1
在一個成熟(常規業務邏輯實現)的產品上,完成本身項目的特定業務邏輯。
框架:規範告終構,基礎功能,但沒有常規業務邏輯實現一種產品。
(ZendFramework,ThinkPHP,YII,symfony,CI 等等)
CREATE DATABASE myimg CHARSET=utf8; GRANT ALL PRIVILEGES ON myimg.* TO 'myimg'@'%' IDENTIFIED BY '123456';
<VirtualHost *:80> DocumentRoot "C:/wamp/www/myimg" ServerName myimg.com <Directory "C:/wamp/www/myimg"> Options FollowSymLinks AllowOverride all Require all granted DirectoryIndex index.php </Directory> </VirtualHost> 127.0.0.1 myimg.com
1.建立單一入口文件 2.聲明路徑常量 3.初始化配置 4.肯定分發參數 5.當前平臺相關的路徑常量 6.註冊自動加載 7.請求分發