PHP入門

一.介紹

PHP(外文名:PHP: Hypertext Preprocessor,中文名:「超文本預處理器」)是一種通用開源腳本語言。語法吸取了C語言、Java和Perl的特色,利於學習,使用普遍,主要適用於Web開發領域。PHP 獨特的語法混合了C、Java、Perl以及PHP自創的語法。它能夠比CGI或者Perl更快速地執行動態網頁。用PHP作出的動態頁面與其餘的編程語言相比,PHP是將程序嵌入到HTML(標準通用標記語言下的一個應用)文檔中去執行,執行效率比徹底生成HTML標記的CGI要高許多;PHP還能夠執行編譯後代碼,編譯能夠達到加密和優化代碼運行,使代碼運行更快。php

PHP 中文手冊
PHP 英文手冊css

二.運行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;"

三.PHP腳本嵌入

標準形式linux

# php代碼後沒有其餘內容結束標記有時能夠省略
<?php
    php代碼
?>
<script  language=」php」>
    php代碼
</script>

短標籤形式(需設置php.ini中short_open_tag = On)正則表達式

<?
.....這裏是php代碼
?>

四.基本語法

  • 變量名區分大小寫
  • 常量名區分大小寫(可設置不區分)
  • 函數名不區分大小寫
  • 系統中使用的關鍵字也不區分大小寫
  • 一個php標記塊中的最後一個分號在有結束標記時可省略
#可省略
<?php
echo 1
?>
#不可省略
<?php
echo 1;

五.變量

使用

  • 變量必須以$開頭,後面緊跟變量名
  • 定義變量:直接給變量賦值,就是定義
<?php
$v1 = 1;
  • 判斷變量是否存在:isset()
    存在就返回true,不存在就返回false,null返回false
<?php
$v1 = null;
echo isset($v1);
  • 判斷變量是否爲空:empty()
<?php
$v1 = null;
$v2 = 0;
$v3 = 1;
echo empty($v1)."===";
echo empty($v2)."===";
echo empty($v3)."===";
  • 修改變量值:直接給變量賦新值
  • 刪除變量:unset()
    unset()斷開變量名跟該變量名所指向的數據的引用

命名規則

基本規則

  1. 只能使用大小寫字母,數字和下劃線(_)
  2. 不能以數字開頭
  3. 不能跟系關鍵字重名

經典命名規則

  1. 匈牙利命名法:該命名法是在每一個變量名的前面加上若干表示數據類型的字符。基本原則是:變量名=屬性+類型+對象描述。如i表示int,全部i開頭的變量命都表示int類型。s表示String,全部變量命以s開頭的都表示String類型變量。
  2. 駱駝命名法:混合使用大小寫字母來構成變量和函數的名字,如userName。
  3. 帕斯卡命名法(pascal命名法):作法是首字母大寫,如UserName,經常使用在類的變量命名中。
  4. 下劃線法:使用小寫字母和下劃線來構成變量和函數的名字,如user_name。

傳值方式

值傳遞(默認)

將一個變量的數據拷貝一份,而後賦值給另外一個變量。算法

引用傳遞

將一個變量的引用拷貝一份,而後賦值給另外一個變量(將另外一個變量指向被引用傳遞變量的數據)。sql

可變變量

一個變量的名是另外一個變量。數據庫

<?php
$v1 = 'v2';
$v2 = 10;
echo $$v1;//10

預約義變量

  • $GLOBALS — 引用全局做用域中可用的所有變量
  • $_SERVER — 服務器和執行環境信息
  • $_GET — HTTP GET 變量
  • $_POST — HTTP POST 變量
  • $_FILES — HTTP 文件上傳變量
  • $_REQUEST — HTTP Request 變量
  • $_SESSION — Session 變量
  • $_ENV — 環境變量
  • $_COOKIE — HTTP Cookies
  • $php_errormsg — 前一個錯誤信息
  • $HTTP_RAW_POST_DATA — 原生POST數據
  • $http_response_header — HTTP 響應頭
  • $argc — 傳遞給腳本的參數數目
  • $argv — 傳遞給腳本的參數數組

超全局變量

PHP 中的許多預約義變量都是「超全局的」,這意味着它們在一個腳本的所有做用域中均可用。在函數或方法中無需執行 global $variable; 就能夠訪問它們。編程

  • $GLOBALS
  • $_SERVER
  • $_GET
  • $_POST
  • $_FILES
  • $_COOKIE
  • $_SESSION
  • $_REQUEST
  • $_ENV

變量序列化

序列化就是將一個變量的數據轉換爲字符串(並非類型轉換),目的是將該字符串進行存儲和傳輸。
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')));//反序列化

六.常量

常量是一個簡單值的標識符(名字),在腳本執行期間該值不能改變。
傳統上常量標識符老是大寫的。

定義常量

  1. 使用define()函數定義
  2. 使用const語法定義
    使用 const 關鍵字定義常量必須處於最頂端的做用區域,由於用此方法是在編譯時定義的。這就意味着不能在函數內,循環內以及 if 語句以內用 const 來定義常量。
  • const和define的區別?
  1. 使用const使得代碼簡單易讀,const自己就是一個語言結構,而define是一個函數。另外const在編譯時要比define快不少。
  2. const用於類成員變量的定義,一經定義,不可修改。define不能夠用於類成員變量的定義,可用於全局常量。
  3. const可在類中使用,define不能
  4. const不能再條件語句中定義常量,define能夠
<?php
define('CONST1', 123);
const CONST2 = 456;

使用常量

  1. 直接使用
  2. 使用constant()函數
<?php
define('CONST1', 123);
echo CONST1;
echo constant('CONST1');//constant(CONST1)->constant('123');

檢查常量:defined()

defined()返回布爾值

<?php
define('CONST1', 123);
echo 'CONST1---'.defined('CONST1');
echo 'CONST2---'.defined('CONST2');

預約義常量

  • 內核預約義常量:是在PHP的內核中就定義好了的常量。區分大小寫。
    PHP_VERSION:返回PHP的版本。
    PHP_OS:返回執行PHP解釋器的操做系統名稱。
    PHP_EOL:系統換行符,Windows是(\r\n),Linux是(\n),MAC是(\r)。
  • 標準預約義常量:PHP默認定義的常量。區分大小寫。
    M_PI:返回π的值。
    M_PI_2:返回π/2的值。
    M_1_PI:返回1/π的值。
<?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__);

八.數據類型

  • 標量類型: int, float, string, bool
  • 複合類型: array, object
  • 特殊類型: null, resouce

1.整數類型(int)

  • 十進制:123
  • 八進制:0123
  • 十六進:0x123

    dec(Decimal): 十進制
    bin(Binary):二進制
    oct(Octal):八進制
    hex(Hexadecimal):十六進制
    ---
    ==十進制是數組,2、8、十六進制是字符串==
    十進制轉二進制decbin()
    十進制轉八進制decoct()
    十進制轉十六進制dechex()
    二進制轉十進制bindec()
    八進制轉十進制octdec()
    十六進制轉十進制hexdec()
<?php
var_dump(decbin(123));
var_dump(bindec('101010'));

2.浮點類型(float, double, real)

  • 普通表示:$v1 = 1.23;
  • 科學計數法表示:$v1 = 1.23E3;($v1 = 123E3;//結果值是123000,但也是一個浮點數。)

浮點數不該直接進行大小比較

應該設置在必定精度要求下比較

<?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);

3.字符串類型(string)

  • 單引號字符串:不識別變量,識別反斜槓單引號轉義字符
  • 雙引號字符串:識別變量和換行回車等轉義字符
  • nowdoc(單引號)定界符字符串:不識別轉義字符
  • heredoc(雙引號)定界符字符串:識別變量,識別轉義字符
<?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
//要有一行

4.布爾類型(bool)

true或false兩個值
隱式轉換爲布爾值是爲false的是:

  1. 0
  2. 0.0
  3. null
  4. ""
  5. "0"
  6. array()
  7. 未定義的變量(會報Notice: Undefined variable)
<?php
if($v1){
  echo 'yse';
}else{
  echo 'no';
}

5.數組類型(array)

分類

  1. 鍵值關係:關聯數組,索引數組
  2. 數組層次:一維數組,二維數組,多維數組

定義

  1. 使用array()方法
  2. 使用變量[]
<?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);

遍歷

數組指針:

  • current($arr); //取得$arr中當前指針所指向的元素的值,若是沒有指向元素,則爲false
  • key($arr); //取得$arr中當前指針所指向的元素的下標
  • next($arr1 ); //將指針移向「下一個元素」,而後取得該下一個元素的值
  • prev($arr); //將指針移向「上一個元素」,而後取得該上一個元素的值
  • reset($arr); //將指針移向「第一個元素」,而後取得該元素的值——數組指針初始化
  • end($arr); //將指針移向「最後一個元素」,而後取得該元素的值
  • each($arr); //取得當前元素的下標和值,而後移動指針到下一個位置。
  1. foreach
    ==foreach不會主動釋放$value==
  • 傳遞方式
    默認值傳遞,引用傳遞要在變量前加&(foreach($arr as $key => &$value){...})
    $key不能設置爲引用傳遞
    由於引用傳遞不會自動銷燬$value因此引用傳遞注意要手動銷燬$value,否則可能不當心通$value修改了數組最後一項。(eg:在兩個循環都用$value時第一個用了引用傳遞,第二個用值傳遞。會將數組最後一項的值改爲倒數第二項)
<?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)
  • foreach過程當中進行修改
    foreach默認是原數組上進行遍歷。
    若是在遍歷過程當中對數組進行了某種修改或使用了數組指針函數,則會複製數組後在複製的數組上繼續遍歷循環。
    foreach中若是值變量是引用傳遞,則不管如何都是在原數組上進行。
<?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並死循環
}
  1. for+next+reset遍歷數組
<?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);//指針移到下一個元素
}
  1. while+each()+list()遍歷數組
<?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);
}

排序

  1. 冒泡排序:倆倆比較大小交換位置
<?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);
  1. 選擇排序:選擇出最大的與最後一個交換
<?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);

查找

  1. 順序查找:直接foreach
  2. 二分查找:必須是排好序而且下標連續的數組
    效率:2^n個數據,須要n次查找

6.對象類型(object)

<?php
class myClass{
  public $v1 = 123;
  public function myfunc(){
    echo $this->v1;
  }
}
$myobj = new myClass();
echo $myobj->v1;
$myobj->myfunc();

7.資源類型(resource)

資源 resource 是一種特殊變量,保存了到外部資源的一個引用。資源是經過專門的函數來創建和使用的。
因爲資源類型變量保存有爲打開文件、數據庫鏈接、圖形畫布區域等的特殊句柄,所以將其它類型的值轉換爲資源沒有意義。

8.空類型(null)

變量沒有指向任何空間

10.類型想關函數

getType(變量名):獲取一個變量的類型名稱
setType(變量名,目標類型字符串):設置一個變量的類型
is_XX類型()系列函數:判斷某個數據是不是某種類型,包括:

  1. is_int()
  2. is_float()
  3. is_bool()
  4. is_numeric()
  5. is_array()
  6. is_string()
  7. is_scalar():判斷是否爲標量類型(即int,float,stirng,bool)
<?php
$v1 = 123;
echo getType($v1)."---";
echo setType($v1, 'string')."---";
echo is_int($v1)."---";
echo is_string($v1)."---";

11.類型轉換

自動轉換

  • 自動轉換是弱類語言的一個最基本也最方便的一個特徵:它會在各類運算中根據運算符的須要也將非該運算符所能處理的數據轉換爲能夠處理的數據。
  • if(數據){}:轉爲bool類型
  • 算術運算符:轉爲數字類型
  • 鏈接運算符:轉爲字符串類型
  • 比較運算符:轉爲布爾類型或數字類型
    兩邊若是有至少一個布爾,則另外一邊就會轉爲布爾,並進行比較
    不然,就轉爲數字進行比較

強制轉換

經過語法來讓某數據轉換爲另外一種類型的數據

<?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 :00000001
    -1:10000001
  • 反碼:
    1 :00000001
    -1:11111110
  • 補碼:(負數是反碼加1)
    1 :00000001
    -1:11111111

計算機中的加減法都是:補碼+補碼=補碼(都轉換成補碼運算)

位運算開關

1:開,0:關

  • 設定
    第一個開:00000001
    第二個開:00000010
    第三個開:00000100
    第四個開:00001000
    第五個開:00010000
    第一,二個開:00000011
    第一,二,五個開:00010011
  • 查詢
    當前狀態 & 查詢狀態(大於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');

運算符的優先級

  1. 括號最優先,賦值最落後
  2. 算術運算符>比較運算符>邏輯運算符(非運算符比算術運算符優先級高)

十:流程控制

程序框圖

  • 開始,結束:橢圓
  • 語句(塊):正方形
  • 判斷:菱形
  • 輸入輸出:平行四邊型

分支結構

  1. if語句
  2. if else 語句
  3. if elseif語句
  4. if elseif else語句
  5. switch語句
<?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;
}

循環結構

  1. while循環
  2. do while循環
  3. for循環
<?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語句(跳轉語句)

嚴重不推薦適用!
它可讓咱們的程序執行流程「任意跳轉」。
語法:
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腳本中止n秒,而後繼續執行:sleep(n);
//PHP默認最長執行執行超過30s可能報錯用set_time_limit()解決。
<?php
echo "start";
sleep(50);
echo "ok";

十一:文件加載

include,include_once,require,require_once(是語言結構,不是函數)

  • 加載/引入/包含/載入不存在的文件include
<?php
//./1.php不存在
include('./1.php');//warning
require('./1.php');//warning error
  • 加上once只會引入一次
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');//不加載
  • 文件加載返回值
    使用include,include_once,require,require_once時成功會返回1
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文件)都有效。

絕對路徑:

  1. 本地絕對路徑:
    window系統: c:/dir1/dir1/test.php
    unix系列系統: /dir1/dir1/test.php
  2. 網絡絕對路徑: http://www.abc.com/dir1/dir1/test.php

只有文件名(不寫路徑)

  1. 首先在php.ini設置的include目錄中查找:
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();
  1. php.ini設置中沒找到,當前工做目錄查(地址欄中顯示的那個文件名所在目錄)
  2. 當前工做目錄中沒找到,則在當前include命令所在文件的目錄中查找

文件加載執行過程

就像是把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

  1. 結束腳本
    return;

  2. 結束腳本帶返回值(在加載腳本的語句接收)
    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 "先定一個小目標,衝他一個億。喵";

錯誤的顯示控制

  • 是否顯示
    php.ini中:
    display_error = On;
    (On顯示,Off不顯示)
    腳本中:
    ini_set(「display_error」, 1);
    (1,true顯示,0,false不顯示)
  • 顯示哪些級別的錯誤
    php.ini中:
    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');//設置文件

自定義錯誤處理

  1. 設定要用來進行自定義處理錯誤的自定義函數名
  2. 本身去定義該函數,並在其中進行任何錯誤信息的輸出(或記錄)
<?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;
}

調用函數

  1. 沒有返回值:直接用
  2. 有返回值:當作一個變量用
  3. 引用傳遞的形參只用能變量當形參
<?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;

函數調用流程

  1. 實際參數傳數據給形式參數
  2. 程序執行流程進入到函數中(一個獨立的運行空間),跟全局執行空間是隔離的
  3. 執行函數內的代碼
  4. 碰到return語句或執行到函數結尾,終止函數的執行,跳回函數開始調用的位置

參數數量

實參能夠多於,少於形參。

<?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');

匿名函數

  1. 將函數賦值給變量
<?php
$myFunc = function(){
    echo "myFunc";
};//這是賦值,這個分號必須有
$myFunc();
  1. 用於可以使用(匿名)函數看成實參的函數(eg:call_user_func_array())
<?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中全局做用域變量函數不能直接使用(js能夠)
  • 超全局做用域:就是在函數的內部和外部均可以使用。
  • 靜態局部做用域:數據可以在函數退出後仍然保持不丟失。

局部訪問全局變

使用:

  1. 局部範圍使用global關鍵字:局部建立同名變量指針指向全局變量對應的數據。
  2. 局部範使用$GLOBALS超全局數組來使用全局變量:直接操做全局變量
<?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

全局訪問局部變量

  1. 在函數內部爲$GLOBALS數組添加元素
  2. 引用傳遞方式傳參數
  3. 引用傳遞方式傳返回值
<?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;

檢查函數是否存在:function_exists(string)

<?php
if(function_exists('link_db') == false){
  function link_db(){
    @mysqli_connect('localhost','123456') or die(mysqli_connect_error());
  }
}
link_db();

字符串函數

查找字符位置函數

  • strpos($str,search,[int]):查找search在$str中的第一次位置從int開始
  • stripos($str,search,[int]):查找search在$str中的第一次位置從int開始(大小寫不敏感)
  • strrpos($str,search,[int]):查找search在$str中的最後一次出現的位置從int開始

提取子字符函數

  • substr($str,$start[,$length]):從$str中strat位置開始提取length長度的字符串
  • strstr($str1,$str2):從$str1(第一個的位置)搜索$str2並從它開始截取到結束字符串
  • stristr($str1,$str2):從$str1(第一個的位置)搜索$str2並從它開始截取到結束字符串(大小寫不敏感)
  • strrchr($str1,$str2):從最後一次搜索到的字符處返回(用處:取路徑中文件名)

替換字符串的PHP字符串函數

  • str_replace(search,replace,$str):從$str中查找search用replace來替換
  • str_ireplace(search,replace,$str):從$str中查找search用replace來替換(大小寫不敏感)
  • strtr($str,search,replace):從$str中查找search到結束用replace來替換(replace不能爲"")
  • substr_replace($str,$rep,$start[,length]):$str原始字符串,$rep替換後的新字符串,$start起始位置,$length替換的長度

比較字符函數

  • strcmp($str1,$str2):$str1>=<$str2分別爲1,0,-1
  • strcasecmp($str1,$str2):$str1>=<$str2分別爲1,0,-1(不分大小寫)
  • strnatcmp($str1,$str2):按天然排序比較字符串
  • strnatcasecmp($str1,$str2):按天然排序比較字符串(區分大小寫)

字符大小寫轉換的PHP字符串函數

  • strtolower($str):字符串轉換爲小寫
  • strtoupper($str):字符串轉換爲大寫
  • ucfirst($str):將函數的第一個字符轉換爲大寫
  • ucwords($str):將每一個單詞的首字母轉換爲大寫

分割成數組的PHP字符串函數

  • str_split($str,len):把$str按len長度進行分割返回數組
  • expload(search,$str[,limit]):把$str按search字符進行分割返回數組
  • split(search,$str[,limit]):把$str按search字符進行分割返回數組(能夠用正則)

正則表達式

  • preg_quote($str);轉義正則表達式字符
  • preg_replace(pattern,replace,$str);正則表達式的搜索和替換
  • preg_match(pattern,$str,$match);匹配正則表達式($match匹配的結果)
  • preg_split(pattern,$str);分隔字符串
  • preg_grep(pattern,$array);返回匹配模式的數組條目

字符長度

  • strlen($str)

去除空格

  • ltrim($str)
  • rtrim($str)
  • trim($str)

加空格函數

  • chunk_split($str,2):向$str字符裏面按2個字符就加入一個空格

HTML代碼有關函數

  • nl2br():轉義HTML
  • strip_tags($str):去除HTML和PHP標記

數據庫相關的PHP字符串函數

  • addslashes($str)

遞歸函數(效率低):函數內部有一條代碼去調用自身(由大到小)

求階乘:

<?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數據庫

==不推薦使用mysql_XXX()這些方法==

  1. 鏈接數據庫
  2. 設定鏈接編碼
    php執行
    mysqli_query($link, 'CHARSET utf8');
    仍是會亂碼(dos下執行CHARSET不會亂碼,而且和SET NAMES utf8同樣改變了client,connection,results)。
  3. 選擇數據庫
  4. 執行sql命令
    mysqli_query執行無返回數據的語句:返回true表示執行成功,返回false失敗
    mysqli_query執行有返回數據的語句:返回對象表示執行成功,返回false失敗
  5. 處理返回結果
<?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);
}

PDO操做數據庫

步驟

  1. 開啓PDO_mysql相關擴展(php_pdo_mysql.dll)
  2. 鏈接
  3. 認證
  4. 發送SQL
  5. 等待mysql服務器的執行結果
  6. 處理執行結果
<?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();

PDO對象的經常使用方法

  1. errorInfo()錯誤信息,包含錯誤信息的數組。
  2. errorCode()錯誤代碼
  3. beginTransaction()開啓事務
  4. rollback()回滾事務
  5. commit()提交事務
  6. inTransaction()判斷是否處於事務中
  7. lastInsertID()最後造成的auto_increment字段的值
  8. Exec(),query():執行SQL的方法,返回值類型不一樣。Exec()返回值類型爲整型表示當前執行SQL所影響的記錄數,query()返回的是對象類型。
    Query():執行查詢類,show,select,desc
    Exec():非查詢類,insert,delete,update,DDL

預處理(預編譯)的執行方式

一條SQL的執行,MySQL分紅兩大步驟:1編譯->2執行
優勢:1.連續執行多條結構相同的SQL速度快(結構已經編譯好了)。2.能夠防止sql注入。

  1. 編譯統一的結構$PDOStatement = $pdo->prepare(SQL的結構);(SQL結構中的數據部分,可使用問號,或者冒號標籤的語法來佔用)
  2. 綁定數據到中間編譯結果$PDOStatement->bindValue()
  3. 執行$PDOStatement->execute();
<?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對象的經常使用方法

  1. errorInfo():錯誤信息
  2. errorCode():錯誤信息
  3. fetch():從結果集中獲取下一行
  4. fetchAll():返回一個包含結果集中全部行的數組
  5. fetchColumn(index=0):容許傳遞參數,表示得到第一條記錄的第幾個字段的值
  6. rowCount():統計處理的記錄數。影響了多少行(增刪改)結果集中存在多少行(查)。
  7. closeCursor():釋放結果集光標(建議fetch以後,手動釋放)。

十五:面向對象

OOP:object oriented program

類與對象

類:是用於描述「某一些具備共同特徵」的物體的概念,是某一類物體的總稱,包括屬性和方法
對象:是指一個具體的「物體」,該物體隸屬於某個「類別」(類)。一般,對象離不開類,沒有類,就不能有對象。

類中成員

一個類的內部能夠有3種代碼:屬性,方法和類常量,它們統稱爲「類中成員」。

通常屬性:就是放在一個類中的變量。

定義形式:

  1. var $v1;//定義不賦值
  2. var $v2 = 2;//定義的同時能夠賦值,該值只能是「直接值」或常量,不能是變量值,也不能是「計算表達式」
  3. public $v1;
  4. public $2 = 2;//其實var是「public」一個別名,正式用public更好。

錯誤定義形式:
$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
使用:

  1. 類::$靜態屬性名;(雙冒號語法,也叫範圍解釋符)
  2. $對象名::$靜態屬性名;(屬於最新的語法,低版本php可能報錯,不推薦使用)
<?php
class C1{
  static $v1 = 123;
}
$o1 = new C1();
echo C1::$v1;
echo $o1::$v1;
//echo $o1->$v1;對象沒法這樣使用靜態屬性

靜態方法:全部對象的公共方法

定義:在定義方法時前面加上static(靜態方法中不能出現$this,只能使用靜態屬性和靜態方法)
使用:

  1. 類::靜態方法名();(雙冒號語法,也叫範圍解釋符)
  2. $對象名::靜態方法名();(屬於最新的語法,低版本php可能報錯,不推薦使用)
<?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());

構造方法

構造方式是類中的一個特殊的方法,其做用是在實例化一個對象的同時,給該對象的屬性賦值,使之一建立完成,就具備了其自己的特有數據(屬性值)。

  1. 該方法名字是固定的,爲:__construct();
  2. 該方法必須是普通方法(不能是靜態方法)
  3. 一般該方法應該是public
  4. 一般該方法中使用$this這個關鍵字來對屬性進行賦值
  5. 當new 類名()的時候,實際上是在調用該構造方法
  6. 若是一個類中定義了構造方法,則實例化該類時就會調用該方法,且實例化時的參數須要跟構造方法的參數匹配
<?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內部的垃圾回收機制)
說明:

  1. 析構方法一般不太須要去定義。
  2. 析構方法不能調用。
  3. 析構方法不能有形參。
  4. 析構方法中能夠用於清理一些在php代碼結束後不能清理的數據,如生成的文件。

對象銷燬的幾個情形:

  1. 腳本程序運行結束,自動銷燬;
  2. 明確地unset()一個對象變量,則被銷燬;
  3. 改變對象變量的值,被銷燬;

實際上,當一個對象沒有任何一個變量指向它的時候,該對象就會被自動銷燬。若是整個程序結束,也會銷燬。

<?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

建立對象:

  1. $對象名 = new 類名();//對象名就是變量名;類是應該定義過了
  2. 用可變類名建立對象
  3. $對象名 = new self;//self指代類自己,這行代碼只能在類內部方法中使用
  4. 經過對象建立對象
  5. 建立空對象,不經過類建立對象(php不能new Object()要用強制類型轉換,用於返回數據)
<?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和大多數面向對象的語言都是單繼承模式。C++是多繼承
  • 擴展:在子類中再來定義本身的一些新的特有的特性信息(屬性,方法和常量)。沒有擴展,繼承也就沒有意義了

類成員的修飾符:

  1. public:公開的,能夠在「任何位置」訪問。
  2. protected:受保護的,能夠在當前類或當前類的上下級具備繼承關係的類中訪問。
  3. private:私有的,只能在其所在的類中訪問
<?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一般用於在子類中調用父類的成員的時候使用,多數一般就是使用父類的「靜態類」成員。由於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

override重寫:

重寫就是將從父類繼承下來的屬性或方法從新定義

  1. 重寫的方法權限應不低於父級權限(私有方法不能被覆蓋,而是在子類中當作全新的使用)
  2. 方法的參數應該跟父類的一致(構造方法參數能夠和父類不一致)
<?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;
  }
}

final class最終類:

若是某個類不但願對其進行擴展,則能夠將其聲明爲最終類。

<?php
final class C1{}
class C2 extends C1{}//會報錯Class C2 may not inherit from final class (C1)

final method最終方法:

若是某個方法不但願被下級類覆蓋,就能夠對其聲明爲最終方法。

<?php
class C1{
  final function final_func(){
    
  }
}
class C2 extends C1{
  function final_func(){
    
  }//會報錯Cannot override final method C1::final_func()
}

抽象類,抽象方法

抽象類

在正常定義類的前面,加上關鍵字:abstract,那就構成抽象類。
抽象類能夠用來規範一些類的共同特性,但又不須要去對其進行實例化。

抽象方法

抽象方法是一個沒有方法體(也不含大括號)的方法。
方法前面須要加上abstract。

抽象類,抽象方法細節

  1. 若是一個方法定義爲抽象方法,則其所在的類必須定義爲抽象類。
  2. 一個抽象類中,能夠沒有抽象方法但一般意義不大。
  3. 子類繼承自一個抽象類,則子類必須實現父類中的全部抽象方法,除非子類也繼續做爲抽象類
  4. 子類實現抽象父類的方法時,訪問控制修飾符的範圍不能下降,且方法的參數也須一致(其實這就是重寫,因此要知足重寫的要求)。
<?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";
  }
}

PHP中的重載

其基本語法是這樣的:
在一個類中,有多個同名的方法,每一個方法的參數不一樣而已。這種現象就稱爲「重載」。
參數不一樣能夠是:數量個數不一樣,或類型不一樣,或順序不一樣。
好比:

class  A{  
int function f1(int x){...}
int function f1(int x, int y){...}
int function f1(string s, int m){...}

但,在php中,一個類中,根本就不能夠定義多個同名方法——這直接是語法錯誤。
實際上,php中的重載指的是:
屬性重載:若是使用一個不存在的屬性,就會去自動調用類中預先定義好的某個方法以處理數據
方法重載:若是使用一個不存在的方法,就會去自動調用類中預先定義好的某個方法以處理該行爲

屬性重載

屬性有4種使用情形:

  1. 取值:$v1 = 對象->屬性;
  2. 賦值:對象->屬性 = XX值;
  3. 判斷是否存在:isset(對象->屬性;)
  4. 銷燬:unset(對象->屬性;)

所謂屬性重載,就是在面對上述4種情形的屬性使用場景中,該對象若是來「應對」的問題。
若是某屬性不存在,但在語法中使用以下情形,則會發生

  1. 取值:$v1 = 對象->屬性; ===>自動調用類中的__get()方法
  2. 賦值:對象->屬性 = XX值; ===>自動調用類中的__set()方法
  3. 判斷是否存在:isset(對象->屬性;) ===>自動調用類中的__isset()方法
  4. 銷燬:unset(對象->屬性;) ===>自動調用類中的__unset()方法
<?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");

interface 接口

接口中只有兩類最簡單特性信息:(沒有普通方法)

  1. 接口常量:其實就是常量
  2. 抽象方法:只有方法名,沒有方法體

接口能夠看做是抽象類的更高層面的抽象規範,不考慮接口常量的話,那麼就至關於之規定了下級類要作什麼,至於怎麼就,沒有規定。
接口能夠實現「多繼承」(多實現),而類不行。
一個類只能繼承一個父類,但能夠實現多個「上級接口」,語法形式:
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);

對象的復(克隆)制clone

淺克隆(默認):只能克隆對象中的「非對象非資源」數據

<?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();

PHP內置標準類

stdclass:該類內部沒有定義任何屬性,但咱們仍是可使用該類的屬性(不存在的屬性)

<?php
var_dump($obj = new stdclass());
$obj->v1 = 1;
$obj->v2 = 2;
var_dump($obj);

將數據轉換爲對象

  1. 對象轉換爲對象:沒有變化
  2. 數組轉換爲對象:數組的鍵名看成屬性名,值爲對應值(數字下標的屬性沒法用"->"操做)
  3. null轉換爲對象:空對象
  4. 其餘標量數據轉換爲對象:屬性名爲固定的「scalar」,值爲該變量的值
<?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()

當對一個對象進行「序列化」操做的時候,會自動調用類中的__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')));

__tostring()
當把一個對象看成一個「字符串」來看待(處理)的時候,會自動調用該魔術方法。
經過該方法,能夠返回「合適」的字符串,也能夠認爲就是對象轉換爲字符串的結果。
若是沒有改方法,會出錯。

<?php
class C1{
  public $v1 = 1;
  public $v2 = 2;
  function __tostring(){
    return "{$this->v1},{$this->v2}";
  } 
}
var_dump((string)new C1());

__invoke()
對象看成一個「方法」(函數)的時候,會自動調用該魔術方法。

<?php
class C1{
  public $v1 = 1;
  public $v2 = 2;
  function __invoke(){
    echo "你怎麼能夠拿對象當函數,好討厭,錘你胸口";
  } 
}
$obj = new C1();
$obj();//打印:你怎麼能夠拿對象當函數,好討厭,錘你胸口

關類和對象的系統函數和運算符

系統函數

  • class_exists():判斷某個類是否存在(定義過)
  • interface_exists():判斷接口是否存在
  • get_class():獲取某個對象的「所屬類名」
  • get_parent_class():獲取某個對象的「所屬父類的類名」
  • get_class_methods():獲取一個類的全部方法,返回一個索引數組,就是這些方法的名字。
  • get_class_vars():獲取一個類的全部屬性,返回一個數組,下標爲屬性名,值爲屬性值。
  • get_declared_classes():得到全部聲明過的類(含系統中的類)
  • is_object():判斷是否對象
  • get_object_vars():得到對象的全部屬性,返回一個數組,下標爲屬性名,值爲屬性值

運算符

  • new:實例化類
  • instanceof:判斷一個對象是不是某個類的「實例」
<?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後期靜態綁定特性:

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個不一樣含義的語法:

  1. 函數中的靜態變量:
function f1(){
    static $v1 = 1;
}
  1. 類中的靜態成員:
class A{
    static $v1 = 1;
    static function f1(){}
}
  1. 方法中的動態指代「當前類」:
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

十七:php開發

二次開發:

在一個成熟(常規業務邏輯實現)的產品上,完成本身項目的特定業務邏輯。

  1. 論壇(discuz,phpwind)
  2. 電商(ecshop,ecmall,shopex)
  3. 內容管理CMS(dede,wordpress)
  4. 社交(ThinkSNS,UCenter Home)

基於框架開發:

框架:規範告終構,基礎功能,但沒有常規業務邏輯實現一種產品。
(ZendFramework,ThinkPHP,YII,symfony,CI 等等)

流程:

  1. 配置數據庫
CREATE DATABASE myimg CHARSET=utf8;
GRANT ALL PRIVILEGES ON myimg.* TO 'myimg'@'%' IDENTIFIED BY '123456';
  1. 配置服務器
<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. 自定義框架
1.建立單一入口文件
2.聲明路徑常量
3.初始化配置
4.肯定分發參數
5.當前平臺相關的路徑常量
6.註冊自動加載
7.請求分發
相關文章
相關標籤/搜索