环境搭建
相关内容可参见《Ubuntu Apache MySQL PHP》。
开发环境需要 PHP 显示错误信息:
sed -i 's/^display_errors = .*$/display_errors = On/g' /etc/php5/apache2/php.inised -i 's/^error_reporting = .*$/error_reporting = E_ALL/g' /etc/php5/apache2/php.ini基本语法
大小写
PHP 是部分大小写敏感的:
- 变量名:大小写敏感
- 常量名:大小写敏感
- 关键字:大小写不敏感
- 函数名:大小写不敏感
- 类名:大小写不敏感
PHP标签
PHP 使用<?php作为代码开始标记,使用?>作为代码结束标记。
<?php // TODO?>指令分隔符
PHP 使用分号(;)作为语句结束标记。
注释
// 单行注释
/* 多行注释*/注意:多行注释不能嵌套使用。
类型
内置类型:
- bool
- int
- float
- string
- array
- object
- resource
- null
bool
$a_bool = true; // 真$a_bool = false; // 假转换为布尔:
var_dump((bool) -1); // bool(true)var_dump((bool) +1); // bool(true)var_dump((bool) 0); // bool(false)var_dump((bool) 0.0); // bool(false)var_dump((bool) ''); // bool(false)var_dump((bool) ' '); // bool(true)var_dump((bool) 'false'); // bool(true)var_dump((bool) '0'); // bool(false)var_dump((bool) '0.0'); // bool(true)var_dump((bool) array()); // bool(false)var_dump((bool) array(5)); // bool(true)var_dump((bool) null); // bool(false)int
$an_int = 1234; // 十进制数$an_int = 0377; // 八进制数$an_int = 0xFF; // 十六进制数转换为整数:
var_dump((int) true); // int(1)var_dump((int) false); // int(0)var_dump((int) 5.3); // int(5)var_dump((int) ''); // int(0)var_dump((int) ' '); // int(0)var_dump((int) '5.3'); // int(5)var_dump((int) 'PHP'); // int(0)var_dump((int) array()); // int(0)var_dump((int) array(5)); // int(1)var_dump((int) null); // int(0)整数溢出:
var_dump(9223372036854775807); // int(9223372036854775807)var_dump(9223372036854775808); // float(9.2233720368548E+18)整数除法:
var_dump(27/6); // float(4.5)var_dump(round(25/6)); // float(4)var_dump(round(29/6)); // float(5)var_dump(floor(29/6)); // float(4)float
$a_float = 1.234;$a_float = 1.2e3;$a_float = 7E-10;转换为浮点数:
var_dump((float) true); // float(1)var_dump((float) false); // float(0)var_dump((float) 5); // float(5)var_dump((float) ''); // float(0)var_dump((float) ' '); // float(0)var_dump((float) '5'); // float(5)var_dump((float) 'PHP'); // float(0)var_dump((float) array()); // float(0)var_dump((float) array(5)); // float(1)var_dump((float) null); // float(0)浮点数比较:
$m = 1.23456789;$n = 1.23456780;$epsilon = 0.00001;
if(abs($m-$n) < $epsilon) { echo 'EQUAL';}string
echo 'escape: single quote \' backslash \\';echo "escape: double quote \" backslash \\";echo "expand: \$variable is {$variable}";转换为字符串:
var_dump((string) true); // string(1) "1"var_dump((string) false); // string(0) ""var_dump((string) 5); // string(1) "5"var_dump((string) 5.3); // string(3) "5.3"var_dump((string) array()); // string(5) "Array"var_dump((string) array(5)); // string(5) "Array"var_dump((string) null); // string(0) ""字符串修改:
$a_string = 'Hello';$a_string[0] = 'Y';字符串拼接:
var_dump('Hello' . 'World'); // string(10) "HelloWorld"var_dump('Hello' + 'World'); // int(0)array
// 索引数组$arr1 = array('value');
// 关联数组$arr2 = array( 'key' => 'value',);元素操作:
// 添加元素$arr1[] = 'value2';$arr2['key2'] = 'value2';
// 修改元素$arr1[0] = 'value1';$arr2['key'] = 'value1';
// 删除元素unset($arr1[0]);unset($arr2['key']);遍历数组:
foreach ($arr1 as $value) { echo $value;}
foreach ($arr2 as $key => $value) { echo "$key => $value";}键名覆盖:
$an_array = array( 0 => 'value1', 1 => 'value2', 1.5 => 'value3', '0' => 'value4', '1' => 'value5', '' => 'value6', false => 'value7', true => 'value8', null => 'value9',);var_dump($an_array); // array(3) { [0]=> string(6) "value7" [1]=> string(6) "value8" [""]=> string(6) "value9" }null
$a_null = null;unset($a_null);转换为其他类型:
var_dump((bool) null); // bool(false)var_dump((int) null); // int(0)var_dump((float) null); // float(0)var_dump((string) null); // string(0) ""var_dump((array) null); // array(0) { }var_dump((object) null); // object(stdClass)#1 (0) { }判断 null:
$a_null === null;is_null($a_null);比较 null:
var_dump(null == true); // bool(false)var_dump(null == false); // bool(true)var_dump(null == 0); // bool(true)var_dump(null == 0.0); // bool(true)var_dump(null == ''); // bool(true)var_dump(null == ' '); // bool(false)var_dump(null == '0'); // bool(false)var_dump(null == array()); // bool(true)var_dump(null == null); // bool(true)
var_dump(null === true); // bool(false)var_dump(null === false); // bool(false)var_dump(null === 0); // bool(false)var_dump(null === 0.0); // bool(false)var_dump(null === ''); // bool(false)var_dump(null === ' '); // bool(false)var_dump(null === '0'); // bool(false)var_dump(null === array()); // bool(false)var_dump(null === null); // bool(true)注意:不要使用==判断 null。
变量
命名规则:
- 变量以美元符号(
$)开头。 - 变量名称以下划线或字母开头。
- 变量名称只能包含下划线、字母、数字。
- 变量名称区分大小写。
变量默认为传值赋值,使用&操作符进行引用赋值。
作用域
函数外部声明的变量,函数内部不能直接访问:
$global_var = '';
// 错误做法function func1() { echo $global_var; // Notice: Undefined variable}
// 正确做法function func2() { global $global_var; echo $global_var;}
// 正确做法function func3() { echo $GLOBALS['global_var'];}函数外部声明的变量,函数内部创建引用的区别:
$global_var1 = '';$global_var2 = '';
// 只在函数内部有效function func1() { global $global_var1, $global_var2; $global_var2 = &$global_var1;}
// 函数内外同时有效function func2() { $GLOBALS['global_var2'] = &$GLOBALS['global_var1'];}函数内部声明的普通变量,只在函数内部有效,且调用结束后释放:
function func_name() { $local_var = ''; echo $local_var;}
echo $local_var; // Notice: Undefined variable函数内部声明的静态变量,只在函数内部有效,且调用结束后不释放:
function func_name() { static $count = 0;
$count++; echo $count;}
func_name(); // 1func_name(); // 2func_name(); // 3
echo $count; // Notice: Undefined variable可变变量
$var_name = 'message';${$var_name} = 'Hello';var_dump($message); // string(5) "Hello"常量
定义常量:
define('PI', 3.14);条件判断中的常量:
// 错误做法if (DEBUG) { echo 'Debug mode.';}
// 正确做法if (defined('DEBUG') && DEBUG) { echo 'Debug mode.';}运算符
算术运算符
- 加(
+) - 减(
-) - 乘(
*) - 除(
/) - 取模(
%) - 递增(
++) - 递减(
--)
字符串运算符
- 连接(
.)
赋值运算符
- 基本赋值
=:$var = $expr
- 组合赋值
+=:$var += $expr等价于$var = $var + $expr-=:$var -= $expr等价于$var = $var - $expr*=:$var *= $expr等价于$var = $var * $expr/=:$var /= $expr等价于$var = $var / $expr%=:$var %= $expr等价于$var = $var % $expr.=:$var .= $str等价于$var = $var . $str
比较运算符
- 宽松相等(
==) - 严格相等(
===) - 宽松不相等(
!=) - 严格不相等(
!==) - 小于(
<) - 小于等于(
<=) - 大于(
>) - 大于等于(
>=)
三元运算符
$var = $true_or_false ? $is_true : $is_false位运算符
- 与(
&) - 或(
|) - 取反(
~) - 异或(
^) - 左移(
<<) - 右移(
>>)
逻辑运算
- 与(
&&) - 或(
||) - 非(
!) - 异或(
xor)
控制结构
if
if ($expression) { echo 'TRUE';} else { echo 'FALSE';}switch
switch ($expression) { case 'value1': // TODO break; case 'value2': // TODO break; case 'value3': // TODO break; default: // TODO break;}while
$index = 0;while ($index < 10) { echo $index;
$index++;}do-while
do { // TODO} while ($expression);for
$count = count($an_array);for ($i = 0; $i < $count; $i++) { echo $an_array[$i];}foreach
foreach ($arr1 as $value) { echo $value;}
foreach ($arr2 as $key => $value) { echo "$key => $value";}循环中的引用:
// 错误做法foreach ($an_array as &$value) { // TODO}// 此时 $value 指向数组最后一个元素
// 正确做法foreach ($an_array as &$value) { // TODO}unset($value); // 明确释放 $valuebreak
break关键字用于结束当前控制结构。
continue
continue关键字用于跳过当前循环迭代的剩余部分。
函数
function关键字用于定义函数。
命名规则:
- 函数名称以下划线或字母开头。
- 函数名称只能包含下划线、字母、数字。
- 函数名称不区分大小写。
参数
赋值参数:
function func_name($var) { // TODO}赋值参数带默认值:
function func_name($var = 'default') { // TODO}引用参数:
function func_name(&$var) { // TODO}返回值
return关键字用于从函数中返回值。
匿名函数
$message = 'welcome to the world of PHP.';
$welcome = function($name) use ($message) { return $name . ', ' . $message;};
echo $welcome('Jane');类
class关键字用于定义类。
class Person { protected $name; protected $age;
public function __construct($name, $age) { $this->name = $name; $this->age = $age; }
public function __destruct() { // TODO }
public function sayHi() { echo "Hi! I'm $this->name. I'm $this->age years old."; }}
$person = new Person('Jane', 18);$person->sayHi();继承
extends关键字用于声明继承类。
class Child extends Person { protected $toy;
public function __construct($name, $age, $toy) { parent::__construct($name, $age);
$this->toy = $toy; }
public function __destruct() { // TODO
parent::__destruct(); }
public function play() { echo "$this->name is playing with a $this->toy."; }}
$child = new Child('Anna', 6, 'doll');$child->play();final
final关键字用于阻止类被继承或者方法被重写。
static
static关键字用于定义静态属性和方法。
class ShapeStatistics { public static $shapeCount = 0; public static $totalArea = 0;
public static function reset() { self::$shapeCount = 0; self::$totalArea = 0; }
public static function add($shape) { self::$shapeCount++; self::$totalArea += $shape->getArea(); }
public static function getShapeCount() { return self::$shapeCount; }
public static function getTotalArea() { return self::$totalArea; }}抽象类
abstract关键字用于声明抽象类。
abstract class Shape { protected $color;
public function __construct($color) { $this->color = $color; }
public function getColor() { return $this->color; }
public function setColor($color) { $this->color = $color; }
abstract public function getArea(); abstract public function showInfo();}
class Circle extends Shape { private $radius;
public function __construct($color, $radius) { parent::__construct($color);
$this->radius = $radius; }
public function getArea() { return 3.14 * $this->radius * $this->radius; }
public function showInfo() { echo 'This is a ' . $this->getColor() . " circle with a radius of $this->radius. Its area is " . $this->getArea() . '.'; }}
class Rectangle extends Shape { private $width; private $height;
public function __construct($color, $width, $height) { parent::__construct($color);
$this->width = $width; $this->height = $height; }
public function getArea() { return $this->width * $this->height; }
public function showInfo() { echo 'This is a ' . $this->getColor() . " rectangle with a width of $this->width and a height of $this->height. Its area is " . $this->getArea() . '.'; }}
$circle = new Circle('blue', 5);$circle->showInfo();
$rectangle = new Rectangle('gray', 9, 8);$rectangle->showInfo();接口
interface关键字用于定义接口,implements关键字用于声明实现接口。
interface ShapeInterface { public function getArea(); public function showInfo();}
class Shape { protected $color;
public function __construct($color) { $this->color = $color; }
public function getColor() { return $this->color; }
public function setColor($color) { $this->color = $color; }}
class Circle extends Shape implements ShapeInterface { private $radius;
public function __construct($color, $radius) { parent::__construct($color);
$this->radius = $radius; }
public function getArea() { return 3.14 * $this->radius * $this->radius; }
public function showInfo() { echo 'This is a ' . $this->getColor() . " circle with a radius of $this->radius. Its area is " . $this->getArea() . '.'; }}
class Rectangle extends Shape implements ShapeInterface { private $width; private $height;
public function __construct($color, $width, $height) { parent::__construct($color);
$this->width = $width; $this->height = $height; }
public function getArea() { return $this->width * $this->height; }
public function showInfo() { echo 'This is a ' . $this->getColor() . " rectangle with a width of $this->width and a height of $this->height. Its area is " . $this->getArea() . '.'; }}
$circle = new Circle('blue', 5);$circle->showInfo();
$rectangle = new Rectangle('gray', 9, 8);$rectangle->showInfo();对象拷贝
默认行为:
class GradeClass { public $gradeName; public $className;
public function __construct($gradeName, $className) { $this->gradeName = $gradeName; $this->className = $className; }}
class Student { public $name; public $gradeClass;
public function __construct($name, $gradeClass) { $this->name = $name; $this->gradeClass = $gradeClass; }}
$student1 = new Student('Zhang San', new GradeClass('IE-Department', '2010-1'));var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(9) "Zhang San" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-1" } }
$student2 = $student1;$student2->name = 'Li Si';$student2->gradeClass->gradeName = 'IE-Department';$student2->gradeClass->className = '2010-2';var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }
$student3 = clone $student1;$student3->name = 'Wang Wu';$student3->gradeClass->gradeName = 'IE-Department';$student3->gradeClass->className = '2010-3';var_dump($student3); // object(Student)#3 (2) { ["name"]=> string(7) "Wang Wu" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-3" } }var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-3" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-3" } }使用__clone()魔术方法:
class GradeClass { public $gradeName; public $className;
public function __construct($gradeName, $className) { $this->gradeName = $gradeName; $this->className = $className; }
public function __clone() { // TODO }}
class Student { public $name; public $gradeClass;
public function __construct($name, $gradeClass) { $this->name = $name; $this->gradeClass = $gradeClass; }
public function __clone() { $this->gradeClass = clone $this->gradeClass; }}
$student1 = new Student('Zhang San', new GradeClass('IE-Department', '2010-1'));var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(9) "Zhang San" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-1" } }
$student2 = $student1;$student2->name = 'Li Si';$student2->gradeClass->gradeName = 'IE-Department';$student2->gradeClass->className = '2010-2';var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }
$student3 = clone $student1;$student3->name = 'Wang Wu';$student3->gradeClass->gradeName = 'IE-Department';$student3->gradeClass->className = '2010-3';var_dump($student3); // object(Student)#3 (2) { ["name"]=> string(7) "Wang Wu" ["gradeClass"]=> object(GradeClass)#4 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-3" } }var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }不使用__clone()魔术方法:
function deepCopy($obj) { return unserialize(serialize($obj));}
class GradeClass { public $gradeName; public $className;
public function __construct($gradeName, $className) { $this->gradeName = $gradeName; $this->className = $className; }}
class Student { public $name; public $gradeClass;
public function __construct($name, $gradeClass) { $this->name = $name; $this->gradeClass = $gradeClass; }}
$student1 = new Student('Zhang San', new GradeClass('IE-Department', '2010-1'));var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(9) "Zhang San" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-1" } }
$student2 = $student1;$student2->name = 'Li Si';$student2->gradeClass->gradeName = 'IE-Department';$student2->gradeClass->className = '2010-2';var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }
$student3 = deepCopy($student1);$student3->name = 'Wang Wu';$student3->gradeClass->gradeName = 'IE-Department';$student3->gradeClass->className = '2010-3';var_dump($student3); // object(Student)#3 (2) { ["name"]=> string(7) "Wang Wu" ["gradeClass"]=> object(GradeClass)#4 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-3" } }var_dump($student2); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }var_dump($student1); // object(Student)#1 (2) { ["name"]=> string(5) "Li Si" ["gradeClass"]=> object(GradeClass)#2 (2) { ["gradeName"]=> string(13) "IE-Department" ["className"]=> string(6) "2010-2" } }命名空间
namespace关键字用于声明命名空间,use关键字用于导入命名空间。
namespace MyProject;
use OtherProject as OP;错误处理
返回特殊值:
function divide($dividend, $divisor) { if ($divisor == 0) { return false; } return $dividend / $divisor;}
$result = divide(10, 0);if ($result === false) { // 处理错误}抛出异常:
function divide($dividend, $divisor) { if ($divisor == 0) { throw new InvalidArgumentException("除数不能为0!"); } return $dividend / $divisor;}
try { $result = divide(10, 0);} catch (InvalidArgumentException $e) { echo $e->getMessage();}其他
类型相关函数
gettype
echo gettype(false); // booleanecho gettype(0); // integerecho gettype(0.0); // doubleecho gettype(''); // stringecho gettype(array()); // arrayecho gettype(new stdClass()); // objectecho gettype(null); // NULLis_xxx
var_dump(is_bool($var)); // 检查变量是否是bool类型var_dump(is_int($var)); // 检查变量是否是int类型var_dump(is_float($var)); // 检查变量是否是float类型var_dump(is_string($var)); // 检查变量是否是string类型var_dump(is_array($var)); // 检查变量是否是array类型var_dump(is_object($var)); // 检查变量是否是object类型var_dump(is_null($var)); // 检查变量是否是null类型var_dump(is_numeric($var)); // 检查变量是否是数字或数字字符串变量相关函数
isset
var_dump(isset($undefined)); // bool(false)
$var = false;var_dump(isset($var)); // bool(true)
$var = 0;var_dump(isset($var)); // bool(true)
$var = 0.0;var_dump(isset($var)); // bool(true)
$var = '';var_dump(isset($var)); // bool(true)
$var = ' ';var_dump(isset($var)); // bool(true)
$var = '0';var_dump(isset($var)); // bool(true)
$var = array();var_dump(isset($var)); // bool(true)
$var = new stdClass();var_dump(isset($var)); // bool(true)
$var = null;var_dump(isset($var)); // bool(false)empty
var_dump(empty($undefined)); // bool(true)
$var = false;var_dump(empty($var)); // bool(true)
$var = 0;var_dump(empty($var)); // bool(true)
$var = 0.0;var_dump(empty($var)); // bool(true)
$var = '';var_dump(empty($var)); // bool(true)
$var = ' ';var_dump(empty($var)); // bool(false)
$var = '0';var_dump(empty($var)); // bool(true)
$var = array();var_dump(empty($var)); // bool(true)
$var = new stdClass();var_dump(empty($var)); // bool(false)
$var = null;var_dump(empty($var)); // bool(true)字符串相关函数
strlen
$str = 'Hello World';echo strlen($str); // 11strpos
$str = 'Hello World';$pos = strpos($str, 'Hello');if ($pos !== false) { echo $pos; // 0}substr
$str = 'Hello World';echo substr($str, 0, 5); // Helloecho substr($str, -5, 5); // Worldstr_replace
$str = 'Hello World';echo str_replace('World', 'PHP', $str); // Hello PHP数组相关函数
array_keys
var_dump( array_keys( array( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) )); // array(3) { [0]=> string(4) "key1" [1]=> string(4) "key2" [2]=> string(4) "key3" }array_key_exists
var_dump( array_key_exists( 'key1', array( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) )); // bool(true)
var_dump( array_key_exists( 'key4', array( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) )); // bool(false)in_array
var_dump( in_array( 'value1', array( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) )); // bool(true)
var_dump( in_array( 'value4', array( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) )); // bool(false)count
echo count(array(1, 2, 3)); // 3