PHP 基礎知識(一)

1. sessionID存儲到cookie中,如果cookie不能用了,session也就失效了。 session印象服務器性能,而且跨服務器的session很難配置。

2. 單引號只轉義 單引號和 \\ 而雙引號轉義很多,如果不加引號,會當作常量去處理。

3. GBK轉車ascii碼 -- 2個字節 UTF8 -- 3個字節 漢字的處理一般都用 mbstring來處理

4. 字符串操作 - 常見任務

=================================

* 提取/查找

* 替換/截斷

* 大小寫轉換

* 轉義/轉編碼

substr()

=========================

字符串截取是最基礎的操作之一,substr函數功能強大,通常使用substr即可完成所有所需操作。

substr_compare() 函數從指定的開始長度比較兩個字符串。

該函數返回:

  • 0 - 如果兩字符串相等
  • <0 - 如果 string1 (從開始位置)小於 string2
  • >0 - 如果 string1 (從開始位置)大於 string2


實戰 - 獲取URL的協議名1

===========================

$url = 'http://weibo.com/rodin';

$url_https = 'https://login.sina.com.cn';

function is_https($url){

return substr($url, 0, 5) === 'https';

}

echo is_https($url) ? 'is secure' : 'not secure';

echo is_https($url_https) ? 'is secure' : 'not secure';

實戰 - 獲取URL的協議名2

===========================

function is_https2($url){

return substr_compare($url, 'https', 0, 5) === 0;

}

實戰 - 獲取URL的協議名3

===========================

parse_url(); -- 判斷url的格式,是否加了協議名稱

function is_https3($url){

$url_components = parse_url($url);

return $url_components['scheme'] === 'https';

}

實戰 - 獲取URL的協議名4

===========================

function is_https4($url){

return $url{0} === 'h'

&& $url{1} === 't'

&& $url{2} === 't'

&& $url{3} === 'p'

&& $url{4} === 's';

}

substr_replace() - 方法說明 -- 函數把字符串的一部分替換為另一個字符串

=========================

substr_replace(string,replacement,start,length)

參數描述string必需。規定要檢查的字符串。replacement必需。規定要插入的字符串。start必需。規定在字符串的何處開始替換。

  • 正數 - 在第 start 個偏移量開始替換
  • 負數 - 在從字符串結尾的第 start 個偏移量開始替換
  • 0 - 在字符串中的第一個字符處開始替換

charlist可選。規定要替換多少個字符。

  • 正數 - 被替換的字符串長度
  • 負數 - 從字符串末端開始的被替換字符數
  • 0 - 插入而非替換


str_ireplace -- 函數使用一個字符串替換字符串中的另一些字符,忽略大小寫

str_replace -- 函數使用一個字符串替換字符串中的另一些字符,該函數對大小寫敏感

preg_replace -- 執行正則表達式的搜索和替換

preg_replace_callback -- 用回調函數執行正則表達式的搜索和替換

實戰 - 過濾危險字符1

==========================

$dangerous='This is dangerous!';

$unsafe = str_replace('>', '>', $dangerous);

$safe = str_replace('

echo $safe;

//一次替換多個

echo str_replace(

array(''), array(''), $dangerous

);

strpos()

=========================

字符串查找是最基礎的操作之一。

系列函數中,默認為從左往右以及大小寫敏感(二進制安全)。

加i的是大小寫忽略(case-insenstive)

加r的是從右往左找,但返回的位置仍然是從左往右。

strpos/stripos 忽略大小寫

strrpos 從後向前 /strripos 忽略大小寫

int|false strpos($haystack, $needle, $offset = null);

//如果在$haystack字符串中查找到了第一個$needle的存在,返回其起始位置;

//否則返回false。

//如果指定了$offset,則會從$offset的位置開始查找,否則從$haystack

//的第一個字符開始查找。

strpos()

=========================

for($i = 0; $i <= 9; $i ++){

echo strpos('9876543210', "$i");

}

explode()

======================

字符串分離,split() 是 explode() 的別名函數

explode/split

implode/join

實戰 - 檢查是否有危險字符存在1

================================

.. code-block:: php

$sql_injection_str = "abcde' or 1=1";

if(strpos($sql_injection_str, "'") !== false){

echo 'suspected sql injection';

}else{

echo 'safe sql string';

}

實戰 - 檢查是否有危險字符存在2

================================

$sql_injection_str = "abcde' or 1=1";

if(count(explode("'", $sql_injection_str)) > 1){

echo 'suspected sql injection';

}else{

echo 'safe sql string';

}

實戰 - 提取文件名1

===========================

$file_name = 'a.rar.zip.html';

$dot_pos = strpos($file_name, '.');

$file_basename = ($dot_pos !== false)

? substr($file_name, 0, $dot_pos)

: $file_name;

echo $file_basename;

實戰 - 提取文件名2

===========================

$file_name = 'a.rar.zip.html';

$file_basename = strstr('.', $file_name, true);

echo $file_basename;

實戰 - 提取文件名3

===========================

.. code-block:: php

$file_name = 'a.rar.zip.html';

list($file_basename,) = explode('.', $file_name, 2);

echo $file_basename;

實戰 - 提取文件名4

===========================

$file_name = 'a.rar.zip.html';

$file_basename = strtok($file_name, '.');

echo $file_basename;


實戰 - 提取文件擴展名1

===========================

//只要最後一個“.“後面的

$file_name = 'a.rar.zip.html';

$dot_pos = strrpos($file_name, '.');

$file_extname = ($dot_pos !== false)

? substr($file_name, $dot_pos + 1) : '';

echo $file_extname;

實戰 - 提取文件擴展名2

===========================

$file_name = 'a.rar.zip.html';

$last_slice = strstr($file_name, '.');

$file_extname = '';

while($last_slice !== false){

$file_extname = substr($last_slice, 1);

$last_slice = strstr($file_extname, '.');

}

echo $file_extname;

實戰 - 提取文件擴展名3

===========================

$file_name = 'a.rar.zip.html';

$file_name_slices = explode('.', $file_name);

$file_extname = count($file_name_slices) > 1

? array_pop($file_name_slices) : '';

echo $file_extname;

實戰 - 提取文件擴展名4

===========================

$file_name = 'a.rar.zip.html';

$token = strtok($file_name, '.');

$file_extname = '';

while($token !== false){

$file_extname = $token;

$token = strtok('.');

}

echo $file_extname;

trim() - Usage

=====================

截掉字符串首尾的回車、換行、Tab(16)、垂直Tab(17)、空格等或者手動指定的字符。

可以用來調整字符串格式、判斷非法字符等功能

trim

ltrim -- 去除左側空格

rtrim/chop -- 去除右側空格

實戰 - 過濾字符串收尾空格

=================================

$a = $_GET['param']; // $_GET['param'] = ' asdf ';

$trimmed_a = trim($a);

$ltrimmed_a = ltrim($a);

$rtrimmed_a = rtrim($a);


echo $trimmed_a; // output: "asdf"

echo $ltrimmed_a; // output: "asdf "

echo $rtrimmed_a; // output: " asdf"


實戰 - 去掉首尾不想要的字符

====================================

$jsonp_string = <<<json>

var data = {

"code" : 1, "error" : "System error", "data" : {null}

};

JSON;

var_dump(json_decode($jsonp_string, 1)); // null


$valid_json_string = trim($jsonp_string, 'var data = ;');

var_dump(json_decode($valid_json_string, 1)); // an array

實戰 - 檢測是否只包含想要的字符

========================================

$file_path = 'sina\\..\\..\\weibo';

$trimmed_path = trim(strtolower($file_path),

"abcdefghijklmnopqrstuvwxyz1234567890\\\");// ..\\..


if($trimmed_path){

echo '不安全的路徑!';

}

//對於此例更易讀的實現是

if(!preg_match('/^[a-z0-9\\\\\\\\]+$/iD', $file_path)){

echo '不安全的路徑!';

}


大小寫轉換 - Usage

===========================

strtolower -- 轉化成小寫

strtoupper -- 轉換成大寫

ucfirst -- 讓第一個字符串大寫

ucwords

實戰 - 忽略大小寫比對字符串

======================================

$a = 'Hello World!';

if(strtolower($a) === 'hello world!'){

echo 'Same!';

}else{

echo 'Different!';

}


實戰 - 忽略大小寫比對字符串2

=======================================

$a = 'Hello worlD!';

if(strcasecmp($a, 'hello world!') === 0){

echo 'Same!';

}else{

echo 'Different!';

}

實戰 - 命名風格轉換

=======================================

$class_name = 'sina_weibo_class';


echo implode('', array_map(

'ucfirst',

explode('_', $class_name)

));

//SinaWeiboClass

實戰 - 命名風格轉換2

=======================================

$class_name = 'sina_weibo_class';

function cb_camel_style($match){

return ucfirst($match[2]);

}

echo preg_replace_callback('/(^|_)(\\w)/i',

'cb_camel_style', $class_name);

//SinaWeiboClass

各種轉義 - Usage

=====================

* HTML轉義:

- htmlentities / html_entity_decode --- 轉移所有字符

- htmlspecialchars / htmlspecialchars_decode --- 轉義個別字符 單引號等等。。。。

* URL轉義:

- urlencode / urldecode

- rawurlencode / rawurldecode(Form兼容)

各種轉義 - Usage

=====================

* JSON轉義:

- json_encode / json_decode(注意溢出)

* SQL轉義:

- addslashes / stripslashes(不推薦)

- PDO::quote (推薦)

數組操作

======================

數組是

.. class:: takahashi3

PHP精髓

http://cn.php.net/manual/en/ref.array.php

.. container:: handout

PHP Web開發使用頻率最高的操作類型

數組常見任務

==================

* 訪問

* 遍歷,過濾,排重,映射

* 排序

* 棧/隊列

* 集合

* 通過SPL擴展

實戰 - 索引數組普通操作

==========================

.. code-block:: php

//Index數組

$a = array(5, 4, 3, 2, 1); // 使用前必須先初始化!

$a[] = 0; // 追加

$a[count($a)] = 1; // Index數組追加

$a[0] === 0; // True

if(isset($a[2])) { //判斷一個index是否存在,或可以檢驗數組長度

echo "Array \\$a's length is bigger or equals to 3";

}

unset($a[1]); // 刪除一個key/index

實戰 - 關聯數組普通操作

==========================

.. code-block:: php

$a = array('a' => 'a_value', 'b' => 'b_value'); // 初始化

$a['c'] = 'c_value';

$a[] = 1; // 追加到當前索引序列的最後一個

if(isset($a['b'])) // 判斷一個key是否已經存在且不為null值

echo "\\$a['b'] is exist and not null";

if(array_key_exists('b', $a))

echo "\\$a['b'] is exist and maybe null";

unset($a['b']); //刪除一個值(或值的引用)

$a['b'] === null; //通過array_key_exists判斷仍然為真

實戰 - 更人性化的逗號1

=========================

.. code-block:: php

$fruits = array('bananas', 'apples', 'pears');

$result = 'I love to eat';

foreach($fruits as $fruit){

$result .= ' ' . $fruit . ',';

}

$result = substr($result, 0, -1) . '.';

echo $result;// I love to eat bananas, apples, pears.

實戰 - 更人性化的逗號2

=========================

.. code-block:: php

$fruits = array('bananas', 'apples', 'pears');

$result = 'I love to eat';

$result .= ' ' . implode(', ', $fruits) . '.';

echo $result;

實戰 - 函數多返回值

=======================

.. code-block:: php

function ugly(&$error_desc){

$error_code = 0;

if(error_detected()){

$error_code = 1;

$error_desc = 'not correct';

}

return $error_code;

}

if(ugly($error_desc)){

echo $error_desc;

}

實戰 - 函數多返回值2

=========================

.. code-block:: php

function beauty(){

$error_code = 0;

if(error_detected()){

$error_code = 1;

$error_desc = 'not correct';

}

return array($error, $error_desc);

}

list($error, $error_detail) = beauty();

if($error) echo $error_detail;

數組 - 集合常見操作

=============================

- 合併數組 array_combine array_merge

- 遍歷: array_walk

- 過濾/排重: array_filter

- 映射: array_map

- 聚合: array_reduce

.. class:: takahashi3

foreach

實戰 - 過濾列表空內容並按id排重

================================

.. code-block:: php

$list = array(

array(

'id' => 12345,

'content' => 'something',

'is_deleted' => false,

),

);

實戰 - 過濾列表空內容並按id排重2

================================

.. code-block:: php

$result = array();

foreach($list as $v){

if($v['is_deleted']){

continue;

}

$result[$v['id']] = $v;

}

實戰 - 過濾列表空內容並按id排重3

====================================

.. code-block:: php

function cb_filter_deleted($item){

static $map;

if($map === null) $map = array();

return !(isset($map[$item['id']])||$item['is_deleted']);

}

$result = array_filter($list, 'cb_filter_deleted');

數組操作 - 排序

=======================

.. class:: takahashi3

sort/usort

asort/uasort

ksort/uksort

...

數組操作 - 棧/隊列

========================

.. class:: takahashi2

array_pop / []

array_shift / array_unshift

數組操作 - 集合

======================

.. class:: takahashi3

array_merge / +

array_intersect

array_diff

...

實戰 - 數據合併

=====================

.. code-block:: php

$a = array('a' => '1', 'b' => '2');

$b = array('a' => 'a', 'c' => 'c');

var_export(array_merge($a, $b));

// array('a'=>'a','b'=>'2','c'=>'c');

var_export($a + $b);

// array('a'=>'1','b'=>'2','c'=>'c');

實戰 - 取交集/差集

=========================

.. code-block:: php

$a = array('a' => '1', 'b' => '2');

$b = array('a' => '1', 'c' => 'c');

var_export(array_intersect($a, $b));

// array('a' => '1');

var_export(array_diff($a, $b));

// array('b' => '2');

數組操作 - SPL擴展

===========================

.. code-block:: php

class SinaArray implements ArrayAccess{

public function offsetSet($key, $value){

echo "array's \"{$key}\" set to \"{$value}\".";

}

//需要實現offsetGet, offsetExists, offsetUnset...

}

$a = new SinaArray();

$a['sina'] = 'weibo';

// output: array's "sina" set to "weibo".

大綱

=====================

.. class:: said

字符串常用操作

-----------------

.. class:: said

數組常用操作

------------------

.. class:: next

Cookie和Session

------------------

.. class:: wait

文件上傳

------------------

.. class:: wait

PHP.ini

------------------

Cookie和Session機制

=========================

.. class:: takahashi4

用戶數據傳輸

Cookie

===============

+ 數據在用戶手中

- 易跨服務器共享

+ 消耗帶寬而非服務器運算和存儲資源

+ 長度有限制

+ 過期時間基本由用戶瀏覽器控制

Cookie

===============

+ 數據 **不可信任**

- 但可通過簽名達到數據信任

+ 容易遭受各種攻擊

- 容易被盜取 XSS

- 容易被劫持會話 CSRF

- 容易被注入 Cookie injection

Session

================

+ 可基於Cookie實現

- 通過識別cookie中的session id實現

+ 數據在服務器上

- 需要公共存儲方可實現跨服務器共享

+ 消耗服務器運算/存儲資源而非帶寬

+ 數據 *基本* 可信任

- 需要防止session id洩漏

+ 不容易遭受攻擊

- 在session id被盜或者被猜測的情況下,仍可能被劫持

Session (2)

================

+ 長度取決於服務器資源

+ PHP代碼中需要開啟 session 支持

+ 默認的Session機制中的過期時間不甚靠譜

+ 存儲機制可 擴展_

.. _擴展: http://cn.php.net/manual/en/book.session.php

大綱

=====================

.. class:: said

字符串常用操作

-----------------

.. class:: said

數組常用操作

------------------

.. class:: said

Cookie和Session

------------------

.. class:: next

文件上傳

------------------

.. class:: wait

PHP.ini

------------------

文件上傳

=======================

.. class:: takahashi3

漏洞簍子

完全版: http://cn.php.net/manual/en/features.file-upload.php

RFC-1867: http://www.ietf.org/rfc/rfc1867.txt

文件上傳 - Usage

======================

.. code-block:: html

<form>/<json>

Send this file:

文件上傳 - Usage

======================

.. code-block:: php

$uploaddir = '/var/www/uploads/';

$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

//TODO 需要做更多的安全檢測,包括文件大小限制

if(move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)){

echo "File is valid, and was successfully uploaded.\\n";

} else {

echo "Possible file upload attack!\\n";

}

文件上傳 - Usage - 安全檢查

================================

.. code-block:: php

$dot_pos = strrpos($_FILES['userfile']['name'], '.');

$file_extname = ($dot_pos !== false)

? strtolower(substr($file_name, $dot_pos + 1))

: '';

$avail_exts = array('jpg', 'jpeg', 'gif', 'png');

if(!in_array($file_extname, $avail_exts)){

echo 'wrong file type';

return;

}

//可能需要對上傳的文件的二進制內容做更進一步判斷

//如gif必須以ascii:gif89a 開頭等

文件上傳 - Usage - 安全檢查2

================================

.. code-block:: php

$file_basename = basename($_FILES['userfile']['name']);

if(preg_match('/^\\w+$/iD', $file_basename){

$uploadfile = "{$file_basename}.{$file_extname}";

}

//簡單粗暴的方法:

$uploadfile = microtime(1).random(1, 999).".{$file_extname}";

文件上傳 - 限制

============================

+ 運行時限制(Post/Request/Memory)

+ 請求執行時間

+ 長連接導致容易受DOS攻擊

+ 易出現安全問題

+ 多服務器/跨IDC同步以及備份

+ 帶寬與連接密集型需要專門優化web服務器

+ 需仔細規劃上傳目錄權限和訪問方法

文件上傳 - 限制

============================

.. class:: takahashi2


Cloud is the God!

+ 雲計算可以解決大部分問題

+ 仍有請求執行時間限制

+ 備份同樣成問題(S3除外)

+ 易遭受DOS攻擊(資源限額耗盡)


大綱

=====================

.. class:: said

字符串常用操作

-----------------

.. class:: said

數組常用操作

------------------

.. class:: said

Cookie和Session

------------------

.. class:: said

文件上傳

------------------

.. class:: next

PHP.ini

------------------

PHP.ini

========================

.. class:: takahashi3

PHP的閘門

完全參考: http://cn.php.net/manual/en/ini.php

PHP.ini - 設置方法

==========================

.. container:: handout

PHP.ini對於CGI/CLI可分開,其中CGI打了fpm補丁時可以再次指定其位置;而CLI可以在運行時指定

+ 位置:

- 通常為安裝目錄,具體需看編譯選項

+ 格式:

- INI

+ 生效:

- 一般需重啟PHP進程,但如果以fcgi模式且打了fpm補丁,則可以不重啟,reload即可

PHP.ini - 設置方法

==========================

+ 其他:

- 命令行下可以通過php -c 來指定ini位置或php -d 來設置某一項的值

- 運行時可以使用 ini_set() / ini_get()

- 也可以使用 `Apache httpd.conf中設置`_

.. _apache httpd.conf中設置: http://ca3.php.net/manual/en/configuration.changes.php

PHP.ini - 格式

==========================

.. code-block:: ini

; allow_call_time_pass_reference

; Default Value: On

; Development Value: Off

; Production Value: Off

allow_call_time_pass_reference = Off


PHP.ini - 常用選項

========================

.. code-block:: ini

expose_php = On

; 大多數情況下,生產服務器應該設置為Off

error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE

; 生產模式一般可以關閉E_NOTICE以防止log過大

display_errors = Off

log_errors = On

error_log = /var/log/php_errors.log

include_path = ".:/usr/share/php"

; 沒有把 . 加入include_path導致在程序裡無法按照相對路徑require

PHP.ini - 常用選項

===============================

.. code-block:: ini

max_execution_time = 30

memory_limit = 128M

; 如果128M還不夠用,請檢查程序邏輯

post_max_size = 8M

register_globals = Off

magic_quotes_gpc = Off

magic_quotes_runtime = Off

PHP.ini - 常用選項

===============================

.. code-block:: ini

allow_url_fopen = On

allow_url_include = Off

default_socket_timeout = 60

date.timezone = Asia/Chongqing

extension=msql.so


課後作業

===================

1. 通讀字符串所有函數手冊;

#. 通讀數組函數所有手冊;

#. 實際操作字符串所有的函數及嘗試其參數組合(可選參數可以忽略);

#. 實際操作數組所有的函數及嘗試其參數組合(可選參數可以忽略);

#. 完成一個文件上傳頁面示例;

#. 修改php.ini中的error_reporting參數進行錯誤控制;

#. 安裝一個php擴展,如memcache或者 pdo_mysql,然後通過php_info()/php -i檢查是否安裝成功。

Thanks

=================

.. class:: takahashi4

Thanks!

Q & A

=================

.. class:: takahashi4

Questions?

str_replace() 過濾危險字符

list() 函數的學習

調試追蹤 debug_backtrace debug_print_backtrace

mysql5.1 的一個bug, select * from user where id in(1,'2'); 這樣的語句在5.1裡面就相當於沒有索引了 會全文檢索,效率可就差了,修改 in (1,2) 或者('1','2')

var_export()

文件上傳的時候 input type=file form的type enctype ...形式

=== 比較的是兩個變量的本身字符 和 類型

__call() __callStatic() 做冗錯機制比較好

================

PHP應用技巧(二)

================

:Email: [email protected]

調查

===========================================

- 知道PHP中INT的最大值

- 瞭解GBK和UTF8

- 使用過mbstring

- PHP中異常與錯誤的區別

目錄

===========================================

- PHP版本比較及特殊流程語句寫法

- 數據類型

- 手冊的使用

- 多字節(中文)字符串處理

- PHP錯誤處理

- 常見錯誤

PHP版本比較

===========================================

============ ===== ======= =======

項目 PHP4 PHP5.2 PHP5.3

============ ===== ======= =======

面向對象支持 差 好 極好

類與對象 是 是 是

訪問控制 否 是 是

析構方法 否 是 是

對象迭代 否 是 是

對象自動加載 否 是 是

命名空間 否 否 是

匿名函數 否 否 是

CGI進程名稱 php php-cgi php-cgi

============ ===== ======= =======

如何選擇PHP版本

===========================================

x.y.z

---------------------------

- x.y 儘量與生服務器一致或高於服務器版本

- z 儘可能的選擇最高版本(非RC/Beta)

有問題的PHP版本

---------------------------

- PHP5.3.5 源代碼被入侵

- ver < PHP5.2.5 json_decode BUG嚴重

PHP特殊的流程控制寫法

===========================================

- switch...case 中可以使用運算語句

- break x 可以跳出多層循環

- if...endif(while/for/foreach等同樣適用) 寫法

- 可變變量 $$a

- 中文變量 $用戶名 = 'xxx';

數據類型

==========================================

弱類型 不等於 無類型

---------------------

======== =========================

int $var = 1;

float $var = 1.0;

string $var = '1';

boolean $var = true;

array $var = array(1,2,3);

Object $var = new stdClass;

NULL $var = null;

Resource $var = fopen('xxx', 'r');

======== =========================

數據類型間的轉換

==========================================

- (int), (integer) - 轉換為 整型(integer)

- (bool), (boolean) - 轉換為 布爾型(boolean)

- (float), (double), (real) - 轉換為 浮點型(float)

- (string) - 轉換為 字符串(string)

- (binary) - 轉換為二進制 字符串(string) (PHP 6)

- (array) - 轉換為 數組(array)

- (object) - 轉換為 對象(object)

- (unset) - 轉換為 NULL (PHP 5)

例:$var = (int)$var;

INT長度限制

==========================================

- 查看INT的最大值可以使用常量(PHP_INT_MAX)

- 32位操作系統INT的最大值為:2147483647

- 64位操作系統INT的最大值為:9223372036854775807

- 面對巨大的整型數字(如UID/微博ID),建議使用字符串表示

數據的比較

==========================================

$a == $b 等於


$a === $b 全等(PHP 4 引進,同時比較類型)

PHP弱類型的底層實現

==========================================

- Zend/zend.h

- struct _zval_struct

- typedef union _zvalue_value

手冊的使用

==========================================

- 手冊是工具

- 手冊是最好的學習資料

- PHP手冊在線/下載地址: http://php.net/docs.php

如何利用手冊查找函數

==========================================

#) 利用索引 **猜**

#) 利用相關函數和索引定位目錄 **找**

#) 利用目錄分類一層一層 **找**

多字節編碼

===========================================

為什麼要用多字節編碼?

-------------------------------------------

處理多字節編碼的字符串需注意些什麼?

-------------------------------------------

如何方便的處理多字節編碼字符串?

-------------------------------------------

多字節編碼(GBK)

===========================================

字符有一字節和雙字節,00–7F(0-127)範圍是一位,和ASCII保持一致,此範圍內嚴格上說有96個文字和32個控制符號。

之後的雙字節中,前一字節是雙字節的第一位。

總體上說第一字節的範圍是81–FE(也就是不含80和FF),第二字節的一部分領域在40–FE,其他領域在80–FE。

參考資料: http://zh.wikipedia.org/wiki/GBK

多字節編碼(UTF-8)

===========================================

- 0xxxxxxx

- 110xxxxx 10xxxxxx

- 1110xxxx 10xxxxxx 10xxxxxx

- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

- 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

- 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

參考資料: http://zh.wikipedia.org/wiki/UTF8

多字節(中文)字符串處理

==========================================

- 設置默認字符集: mb_internal_encoding('utf-8');

- 獲取字數: mb_strlen();

- 按字數截取字符串: mb_substr();

- 獲取字符寬度: mb_strwidth();

- 按字符寬度截取: mb_strimwidth();

- 按字節數截取: mb_strcut();

- 編碼轉換:mb_convert_encoding();

PHP錯誤處理

==========================================

控制錯誤的輸出

----------------------------------

自定義錯誤處理程序

----------------------------------

出錯後如何定位出出錯的地方

----------------------------------

PHP的錯誤級別

==========================================

影響PHP錯誤輸出的相關配置

--------------------------

#) php.ini

#) error_reporting

#) display_errors

#) runtime php code

#) error_reporting()

#) ini_set()

error_reporting 配置

==========================================

- 配置值參考: http://hk.php.net/manual/zh/errorfunc.constants.php

- 配置方法參考:

- E_ALL

- E_ALL & ~E_NOTICE

- E_ALL | E_STRICT

- E_ALL | E_STRICT & ~E_NOTICE

自定義錯誤處理程序

==========================================

- 自定義錯誤函數 set_error_handler

- 自定義異常處理 set_exception_handler

- 還原系統默認處理錯誤函數 restore_error_handler

- 還原系統默認處理異常 restore_exception_handler

- 拋出用戶自定義錯誤 trigger_error (E_USER_*)

調試追蹤

==========================================

- 究竟外層是怎麼調用到底層方法的?

- debug_backtrace

- debug_print_backtrace

- 有沒有更好的辦法?

- 結合 set_error_handler,出錯後自動追蹤

常見錯誤

==========================================

語言本身的誤導性

--------------------------------

寫錯的語句仍可解析為正確語句

--------------------------------

手冊的不完整性

--------------------------------

編寫PHP代碼不嚴謹

--------------------------------

……

--------------------------------

常見錯誤(頭已輸出)

==========================================

**Cannot modify header information - headers already sent by xxx**

- 發送header(含cookie)前不要有任何輸出

- 注意 *

- 如果當前文件只有PHP代碼,可不寫 *?>*

- 注意是否有utf8 BOM頭

常見錯誤(==)

==========================================

.. code-block:: php

$a = 'weibo';

if($a = 't') {

echo 'true';

} else {

echo 'false';

}

//結果輸出true

常見錯誤(優先級)

==========================================

.. code-block:: php

$result = (int) 0.1+0.9;

echo $result;

//結果輸出0.9

常見錯誤(分號)

==========================================

.. code-block:: php

$var = false;

if($var);

{

echo 'ok';

}

//以上程序會輸出ok

常見錯誤(類型轉換後的值)

==========================================

.. code-block:: php

$a = false;

$a = (array)$a;

if($a) {

echo 'true';

} else {

echo 'false';

}

//結果輸出true

常見錯誤(丟失的數組KEY)

==========================================

.. code-block:: php

$arr = array(

110 => 'weibo',

111 => 'event',

112 => 'q',

113 => 'screen',

114 => 'service',

);

$result = array_slice($arr, 1, 3);

print_r($result);

常見錯誤(PHP BUG)

==========================================

PHP BUG: http://bugs.php.net/

謝謝大家

============

:Author: @李棖煊 (4061)

:Email: [email protected]

作業

==========================================

- 閱讀手冊mbstring部分

- 嘗試使用mbstring函數

- 嘗試調節各種錯誤級別設置

- 瞭解 https://bugs.php.net/

- 瞭解UTF8編碼 http://zh.wikipedia.org/wiki/UTF8 (可選)

- 編寫一個自定義錯誤函數,將錯誤轉換為異常 (可選)


PHP 基礎知識(一)


分享到:

閱讀更多 老公城獅 的文章

關鍵字: Scheme 基礎知識 PHP


相關文章: