编程教育资源分享平台

网站首页 > 后端开发 正文

PHP 基础知识(一)

luoriw 2024-01-31 12:32:44 后端开发 20 ℃ 0 评论

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

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

<?php

$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

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

<?php

function is_https2($url){

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

}

实战 - 获取URL的协议名3

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

parse_url(); -- 判断url的格式,是否加了协议名称

<?php

function is_https3($url){

$url_components = parse_url($url);

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

}

实战 - 获取URL的协议名4

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

<?php

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

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

<?php

$dangerous='This<script src="http://x.cn/xss.js"></script> is dangerous!';

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

$safe = str_replace('<', '<', $unsafe);

echo $safe;

//一次替换多个

echo str_replace(

array('<', '>'), array('<', '>'), $dangerous

);

strpos()

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

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

系列函数中,默认为从左往右以及大小写敏感(二进制安全)。

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

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

strpos/stripos 忽略大小写

strrpos 从后向前 /strripos 忽略大小写

<?php

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

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

//否则返回false。

//如果指定了$offset,则会从$offset的位置开始查找,否则从$haystack

//的第一个字符开始查找。

strpos()

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

<?php

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

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

}

explode()

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

字符串分离,split() 是 explode() 的别名函数

explode/split

implode/join

实战 - 检查是否有危险字符存在1

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

.. code-block:: php

<?php

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

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

echo 'suspected sql injection';

}else{

echo 'safe sql string';

}

实战 - 检查是否有危险字符存在2

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

<?php

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

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

echo 'suspected sql injection';

}else{

echo 'safe sql string';

}

实战 - 提取文件名1

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

<?php

$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

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

<?php

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

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

echo $file_basename;

实战 - 提取文件名3

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

.. code-block:: php

<?php

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

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

echo $file_basename;

实战 - 提取文件名4

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

<?php

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

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

echo $file_basename;


实战 - 提取文件扩展名1

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

<?php

//只要最后一个“.“后面的

$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

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

<?php

$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

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

<?php

$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

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

<?php

$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 -- 去除右侧空格

实战 - 过滤字符串收尾空格

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

<?php

$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"


实战 - 去掉首尾不想要的字符

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

<?php

$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

实战 - 检测是否只包含想要的字符

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

<?php

$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

实战 - 忽略大小写比对字符串

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

<?php

$a = 'Hello World!';

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

echo 'Same!';

}else{

echo 'Different!';

}


实战 - 忽略大小写比对字符串2

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

<?php

$a = 'Hello worlD!';

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

echo 'Same!';

}else{

echo 'Different!';

}

实战 - 命名风格转换

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

<?php

$class_name = 'sina_weibo_class';


echo implode('', array_map(

'ucfirst',

explode('_', $class_name)

));

//SinaWeiboClass

实战 - 命名风格转换2

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

<?php

$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

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

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

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

<?php

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

$result = 'I love to eat';

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

echo $result;

实战 - 函数多返回值

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

.. code-block:: php

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

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

<?php

$list = array(

array(

'id' => 12345,

'content' => 'something',

'is_deleted' => false,

),

);

实战 - 过滤列表空内容并按id排重2

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

.. code-block:: php

<?php

$result = array();

foreach($list as $v){

if($v['is_deleted']){

continue;

}

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

}

实战 - 过滤列表空内容并按id排重3

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

.. code-block:: php

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

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

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

<?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 action="__URL__" method="POST" enctype="multipart/form-data">

<!-- MAX_FILE_SIZE 可以限制文件大小-->

<input type="hidden" name="MAX_FILE_SIZE" value="30000" />

<!-- $_FILES 数组中用来识别的名字-->

Send this file: <input name="userfile" type="file" />

<input type="submit" value="上传文件" />

</form>

文件上传 - Usage

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

.. code-block:: php

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

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

<?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应用技巧(二)

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

:作者: @李枨煊 (4061)

:Email: chengxuan@staff.sina.com.cn

调查

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

- 知道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* 前有没有空格

- 如果当前文件只有PHP代码,可不写 *?>*

- 注意是否有utf8 BOM头

常见错误(==)

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

.. code-block:: php

<?php

$a = 'weibo';

if($a = 't') {

echo 'true';

} else {

echo 'false';

}

//结果输出true

常见错误(优先级)

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

.. code-block:: php

<?php

$result = (int) 0.1+0.9;

echo $result;

//结果输出0.9

常见错误(分号)

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

.. code-block:: php

<?php

$var = false;

if($var);

{

echo 'ok';

}

//以上程序会输出ok

常见错误(类型转换后的值)

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

.. code-block:: php

<?php

$a = false;

$a = (array)$a;

if($a) {

echo 'true';

} else {

echo 'false';

}

//结果输出true

常见错误(丢失的数组KEY)

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

.. code-block:: php

<?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: chengxuan@staff.sina.com.cn

作业

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

- 阅读手册mbstring部分

- 尝试使用mbstring函数

- 尝试调节各种错误级别设置

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

- 了解UTF8编码 http://zh.wikipedia.org/wiki/UTF8 (可选)

- 编写一个自定义错误函数,将错误转换为异常 (可选)


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表
最新留言