PHP原始为Personal Home Page
的缩写,已经正式更名为 PHP: Hypertext Preprocessor
(超文本预处理器的字母缩写) PHP是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML中,尤其适合 web 开发。 PHP 脚本主要用于以下三个领域:服务端脚本,命令行脚本,编写桌面应用程序
四种标量类型:string
integer
float
boolean
两种复合类型:array
object
两种特殊类型:resource
NULL
回调类型: callback
string
值赋给变量 $var
,$var
就成了一个 string
。如果又把一个integer
赋给 $var
,那它就成了一个integer
。 PHP 的自动类型转换的一个例子是加法运算符+
。如果任何一个操作数是float
,则所有的操作数都被当成float
,结果也是float
。否则操作数会被解释为integer
,结果也是integer
。注意这并没有改变这些操作数本身的类型;改变的仅是这些操作数如何被求值以及表达式本身的类型。(int)
(integer)
- 转换为整形 integer
(bool)
(boolean)
- 转换为布尔类型 boolean
(float)
(double)
(real)
- 转换为浮点型 float
(string)
- 转换为字符串 string
(array)
- 转换为数组 array
(object)
- 转换为对象 object
(unset)
- 转换为 NULL
(PHP 5)(binary)
b"string"
- 换为二进制字符串__LINE__
文件中的当前行号。 __FILE__
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,__FILE__
总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。 __DIR__
文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)
。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增) __FUNCTION__
函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。 __CLASS__
类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar
)。注意自 PHP 5.4 起 __CLASS__
对 trait 也起作用。当用在 trait 方法中时,__CLASS__
是调用 trait 方法的类的名字。 __TRAIT__
Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。Trait 名包括其被声明的作用区域(例如 Foo\Bar
)。 __METHOD__
类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。 __NAMESPACE__
当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。
__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep()
__wakeup()
__toString()
__invoke()
__set_state()
__clone()
超全局变量
— 超全局变量是在全部作用域中始终可用的内置变量 $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
— 传递给脚本的参数数组
gettype( PHP_INT_MAX + 1 ); function_exists('print'); (int) ( ( 0.1 + 0.7) * 10 ); is_nan( acos( 8 ) ); ( bool )'0'; false || true; array( 1 => "a", "1" => "b", 1.5 => "c", true => "d" ); array( "a", "b", 6 => "c", "d" ); count( 'string' ); count( null ); $null = null; isset( $null ); $object = (object) 'string'; $object->scalar; 8 % ( -2 ); $srcArr = array( 'a', 'b', 'c', 'd' ); is_string( array_rand( $srcArr ) ); $a = 1; function sum(){ echo $a;} sum();
count 返回值 ¶ isset 说明 ¶ 转换为对象 ¶ 你可能注意到 PHP 的全局变量和 C 语言有一点点不同,在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖。这可能引起一些问题,有些人可能不小心就改变了一个全局变量。PHP 中全局变量在函数中使用时必须声明为 global。 变量范围 ¶
$a = $a - $b; $b = $b + $a; $a = $b - $a; /* 优点:运算简单 ;缺点:只支持整形,存在溢出问题(精度丢失) */ $a = $a ^ $b; $b = $b ^ $a; $a = $a ^ $b; /* 优点:运算简单 ,不纯在溢出问题;缺点:字符串长度相同时才能正确交换,若是两个数值相同的数 就不能交换 */ $a .= $b; $b = substr($a, 0, ( strlen($a) - strlen($b) ) ); $a = substr($a, strlen($b) ); /* 优点:支持字符串和整形,以及格式化的数组,对象等,不存在溢出问题 */ $a .= $b; $b = str_replace( $b, "", $a ); $a = str_replace( $b, "", $a ); /* 字符串改进版 */ list($var1, $var2) = array($var2, $var1); /* 优点:通用 */
function () { return max(func_get_args()); };
echo 不是一个函数(它是一个语言结构), 因此你不一定要使用小括号来指明参数,单引号,双引号都可以。 echo (不像其他语言构造)不表现得像一个函数, 所以不能总是使用一个函数的上下文。 另外,如果你想给echo 传递多个参数, 那么就不能使用小括号。 没有返回值。
print 实际上不是一个函数(它是一个语言结构),因此你可以不必使用圆括号来括起它的参数列表。总是返回 1。
print_r() 显示关于一个变量的易于理解的信息。如果给出的是 string、integer 或 float,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
#语言结构/函数,参数,返回值 echo $a, $b, PHP_EOL; print $a . $b . PHP_EOL; print_r(array($a,$b,PHP_EOL), true);
strrev($s); // 中文乱码 preg_match_all('/./u', $s, $match); implode('', array_reverse($match[0])); $length = mb_strlen($s); $r = ''; while($length) { $r .= mb_substr($s, --$length, 1, 'utf-8'); }
implode(' ', array_reverse(explode(' ', $s)));
strrev(implode(',', str_split(strrev($n), 3))); number_format($n); ltrim(strrev(chunk_split(strrev($n), 3, ',')), ','); preg_replace('/(?<=\d{3})(\d{3})/',', $1', preg_replace('/^(\d{1,3})((\d{3})+)$/','$1,$2',$n));
从版本 4.3.0 开始,PHP 提供了一种新类型的 CLI SAPI(Server Application Programming Interface,服务端应用编程端口)支持,名为 CLI,意为 Command Line Interface,即命令行接口。顾名思义,该 CLI SAPI 模块主要用作 PHP 的开发外壳应用。CLI SAPI 和其它 CLI SAPI 模块相比有很多的不同之处,我们将在本章中详细阐述。值得一提的是,CLI 和 CGI 是不同的 SAPI,尽管它们之间有很多共同的行为。
以下为 CLI SAPI 和其它 CLI SAPI 模块相比的显著区别:
CLI SAPI 模块有以下三种不同的方法来获取要运行的 PHP 代码:
通过标准输入(stdin)提供需要运行的 PHP 代码 : some_application | some_filter | php | sort -u >final_output.txt |
getopt('f:sed::', array('option::')); !php % -f'/home/' -f ~ --option=\a\b\c $argv; !php % '/home' fgets(STDIN);
function extension($filename) { $pathinfo = pathinfo($filename); return strtolower($pathinfo['extension']); }
被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告;这一点和 require 不同,后者会发出一个致命错误。
如果定义了路径——不管是绝对路径(在 Windows 下以盘符或者 \ 开头,在 Unix/Linux 下以 / 开头)还是当前目录的相对路径(以 . 或者 .. 开头)——include_path 都会被完全忽略。例如一个文件以 ../ 开头,则解析器会在当前目录的父目录下寻找该文件。
require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行。
__DIR__; __FILE__; getopt(); $argv; $_REQUEST; $_PUT = file_get_contents('php://input');
$b = array_count_values($a); arsort($b);
#nginx.conf client_max_body_size 10M #php.ini upload_max_filesize 所上传的文件的最大大小。 post_max_size 设定 POST 数据所允许的最大大小。 memory_limit 设定了一个脚本所能够申请到的最大内存字节数。 /*Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. If memory limit is enabled by your configure script, memory_limit also affects file uploading. Generally speaking, memory_limit should be larger than post_max_size. */
date('Y-n-j H:i:s',strtotime('-1 days));
date('Y-m-d', strtotime('last day of -1 months')); date('Y-m-d', strtotime('first day of -1 months')); strtotime('-1 days', strtotime(date('Y-m-01', time()))); //上一月的最后一天 mktime(0, 0, 0, date('m')-1, 1, date('Y')); //上一月的第一天
in_array(array('id' => 500), $a);
str_word_count($string);
octdec('012'); (int)012;
error_reporting(E_ALL); ini_set('display_errors', 1);
elseif可以用于冒号,而else if则不能。
preg是与Perl兼容正则表达式(Regular Expressions(Perl-Compatible));ereg以POSIX为基础(Regular Expression (POSIX Extended)),UNIX的可移植操作系统接口(As of PHP 5.3.0 this extension is deprecated, calling any function provided by this extension will issue an E_DEPRECATED notice).
模式需要由分隔符闭合包裹。分隔符可以使任意非字母数字、非反斜线、非空白字符。 经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)
$link = '<a href="http://yanpeipan.github.io/" title="PHP面试总结">PHP面试总结</a>'; preg_match('/href="(.*)"/U', $link, $match);
除了使用正则之外,还可以使用Data Filtering ¶
preg_match('/^[\d\w-_]+@[\d\w-_]+(\.[\d\w-_]+)+$/', $email, $match); filter_var($email, FILTER_VALIDATE_EMAIL);
if (preg_match('/(?<!\d)(?:[\d]{4}+-?\d{1,2}-?\d{1,2})(?!\d)/', $title, $match)) { var_dump($match); }
在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的 hardlink。 写复制(copy on write) 写改变(change on write)
应该避免使用引用,除非你非常清楚要做什么,如调用函数修改多个变量。
$a = array('a', 'b', 'c'); foreach($a as $key => $value) { $val = &$a[$key]; }
Session 简介 ¶ session被用于表示一个持续的连接状态,在网站访问中一般指代客户端浏览器的进程从开启到结束的过程。session其实就是网站分析的访问(visits)度量,表示一个访问的过程。PHP session 变量用于存储有关用户会话的信息,或更改用户会话的设置。Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用。
cookie 是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递。用户每次访问站点时,Web应用程序都可以读取cookie包含的信息。
cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力,定义于:IETF RFC 2965 HTTP State Management Mechanism
cookie分为二种:
浏览器的cookie被禁止后session就需要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现。
1. 作用 : session被用于表示一个持续的连接状态;cookie被用于跟踪会话 2. 作用域 : Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用;cookie path/domain,同源策略 3. 数据 : session存放于服务端,cookie存放于客户端,并会被附加在每个HTTP请求中;在发送 cookie 时 4. 编码 :cookie 的值会自动进行 URL 编码,在取回时进行自动解码 4. 生命周期 : session在session.gc_maxlifetime之后有几率被回收;持久cookie会在过期后立刻失效;临时cookie生命周期为浏览器会话期间 5. 安全性 : 客户端可以查看/修改cookie;cookie是通过HTTP协议明文传递的;session对用户是透明的;(cookie窃取与会话劫持) 6. 限制 : Cookie的大小限制在4KB左右
深入理解PHP原理之Session Gc的一个小概率Notice
在php中,session的回收机制主要依靠三个配置共同实现(在php.ini文件中),分别是: session.gc_maxlifetime = 1440 ;设置php session的有效期 session.gc_probability = 1 ;设置gc回收机制的被除数 session.gc_divisor = 100 ;设置gc回收机制的除数 在PHP中, 如果使用file_handler作为Session的save handler, 那么就有概率在每次session_start的时候运行Session的Gc过程。 session gc被触发时,就会检查/tmp/sess_*的文件, 如果最后的修改时间到现在超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过期失效. 其调用概率相当于session.gc_probability/session.gc_divisor。 对于大型网站来说,频繁地回收会给服务器带来很大的开销, 一般会将session.gc_probability/session.gc_divisor设置的足够小。
header('Content-type: application/pdf'); header('Content-Disposition: attachment; filename="保存时的文件名.pdf"');
使用domain属性只能实现AJAX跨子域访问; iframe需要双方服务器请求和被请求页面都要做轮询监听location对象的hash属性; 使用script标记则要求被访问数据格式为js可调用的变量或函数; 使用flash调用需要被请求服务器根目录有crossdomain.xml文件; 使用jsonp需要被请求服务器接受地址加回调函数参数和返回json数据; Ajax请求本地的php,由php通过fopen完成跨域请求; 设置本域apache服务器的反向代理。
设计模式_Gang of Four](http://book.douban.com/subject/1052241/) [_PHP高级程序设计 深入PHP:面向对象、模式与实践(第2版)
class Observable implements SplSubject { private $storage; function __construct() { $this->storage = new SplObjectStorage(); } function attach(SplObserver $observer) { $this->storage->attach($observer); } function detach(SplObserver $observer) { $this->storage->detach($observer); } function notify() { foreach ($this->storage as $obj) { $obj->update($this); } } //... } abstract class Observer implements SplObserver { private $observable; function __construct(Observable $observable) { $this->observable = $observable; $observable->attach($this); } function update(SplSubject $subject) { if ($subject === $this->observable) { $this->doUpdate($subject); } } abstract function doUpdate(Observable $observable); } class ConcreteObserver extends Observer { function doUpdate(Observable $observable) { //... } } $observable = new Observable(); new ConcreteObserver($observable);
class Singleton { protected static $_instance = null; protected function __construct() { } protected function __clone() { //disallow clone trigger_error('Clone is not allow !', E_USER_ERROR); } public function getInstance() { if (static::$_instance === null) { static::$_instance = new static; } return static::$_instance; } } class D extends Singleton { protected static $_instance = null; } $c = Singleton::getInstance(); $d = D::getInstance(); var_dump($c === $d);
PHP Predefined Interfaces 预定义接口 Predefined Interfaces and Classes ¶
This interface has no methods, its only purpose is to be the base interface for all traversable classes.
if( !is_array( $items ) && !$items instanceof Traversable ) //Throw exception here
Interface for external iterators or objects that can be iterated themselves internally.
Iterator extends Traversable { //返回当前索引游标指向的元素 abstract public mixed current(void) //返回当前索引游标指向的元素的键名 abstract public scalar key(void) //移动当前索引游标指向下一元素 abstract public void next(void) //重置索引游标的指向第一个元素 abstract public void rewind(void) //判断当前索引游标指向的是否是一个元素,常常在调用 rewind()或 next()使用 abstract public boolean valid(void) }
The IteratorAggregate interface ¶
class myData implements IteratorAggregate { public $property1 = "Public property one"; public $property2 = "Public property two"; public $property3 = "Public property three"; public function __construct() { $this->property4 = "last property"; } public function getIterator() { return new ArrayIterator($this); } } $obj = new myData; foreach($obj as $key => $value) { var_dump($key, $value); echo "\n"; }
Interface to provide accessing objects as arrays.
ArrayAccess { /#### Methods ####/ abstract public boolean offsetExists ( mixed $offset ) abstract public mixed offsetGet ( mixed $offset ) abstract public void offsetSet ( mixed $offset , mixed $value ) abstract public void offsetUnset ( mixed $offset ) }
Serializable { /#### Methods ####/ abstract public string serialize ( void ) abstract public void unserialize ( string $serialized ) }
class A { private static $sfoo = 1; private $ifoo = 2; } $cl1 = static function() { return A::$sfoo; }; $cl2 = function() { return $this->ifoo; }; $bcl1 = Closure::bind($cl1, null, 'A'); $bcl2 = Closure::bind($cl2, new A(), 'A'); echo $bcl1(), "\n"; echo $bcl2(), "\n"; /################################################################################################################/ class A { function __construct($val) { $this->val = $val; } function getClosure() { //returns closure bound to this object and scope return function() { return $this->val; }; } } $ob1 = new A(1); $ob2 = new A(2); $cl = $ob1->getClosure(); echo $cl(), "\n"; $cl = $cl->bindTo($ob2); echo $cl(), "\n";
SPL是Standard PHP Library(PHP标准库)的缩写。 根据官方定义,它是”a collection of interfaces and classes that are meant to solve standard problems”。但是,目前在使用中,SPL更多地被看作是一种使object(物体)模仿array(数组)行为的interfaces和classes。 PHP SPL笔记 PHP标准库 (SPL) ¶
$fp = fopen("lock.txt", "w+");//本地测试文件加下的txt文件,为了测试,可以为空或者写入一些东西 if (flock($fp, LOCK_EX)) { // 进行排它型锁定 fwrite($fp, "Write something here\n"); flock($fp, LOCK_UN); // 释放锁定 echo 123; }
1 有效使用缓存,增加缓存命中率 2 使用负载均衡 3 对静态文件使用CDN进行存储和加速 4 想法减少数据库的使用 5 查看出现统计的瓶颈在哪里
php-langspec PHP官方手册 PHP编码规范 PHP-FIG PSR中文版
Yan Peipan 27 November 2014