PHP
介绍
超文本预处理器
通用开源的服务端脚本语言
网站编程、WEB开发领域
弱类型语言
基本概念
Hello World
php
<?php
echo 'hello world';
?>
注释
php
// 打印hello world
echo 'hello world';
/**
* php学习:
* print vs echo
* 尽量选择用echo
*/
print 'hello world from print';
变量
变量以$
开头,后跟变量名称,变量名以字母和下划线开始
变量名只能包含字母、数字和下划线
变量名区分大小写
php
$age = 25;
$salary = 5000;
$nextSalary = $salary * ($age - 20) * 10 / 100;
echo $nextSalary;
字符串变量
单引号 or 双引号
php
$txt = 'Hello World!';
echo $txt;
echo PHP_EOL;
并置运算符
php只有一个字符串运算符,并置运算符.
,用于将两个字符串相连
php
$txt1 = 'Hello World';
$txt2 = 'PHP';
echo $txt1 . ", " . $txt2;
echo PHP_EOL;
长度
php
$txt = 'Hello World!';
echo strlen($txt);
echo PHP_EOL;
查找
php
$txt = 'Hello World!';
echo strpos($txt, 'llo');
echo PHP_EOL;
作用域
全局作用域:函数外部定义的变量,可以被除函数外的任何部分访问,函数内访问全局变量需要global
关键字
局部作用域:函数内部定义的变量,仅能在函数内访问
参数作用域:函数参数列表中声明的变量,在函数调用时将值传递给参数变量
php
$globalVar = 500;
function getVar(): void
{
global $globalVar;
$var = 800;
echo $globalVar++;
echo PHP_EOL;
echo $var;
echo PHP_EOL;
}
getVar();
echo $globalVar;
echo PHP_EOL;
echo $var;
echo PHP_EOL;
global
关键字实现了在函数内访问全局变量
局部变量会随着函数执行完成而被删除,如果不希望局部变量被删除,可以在局部变量声明时使用static
关键字
php
function getStaticVar(): void
{
static $staticVar = 0;
$staticVar++;
echo $staticVar;
echo PHP_EOL;
}
getStaticVar();
getStaticVar();
getStaticVar();
运算符
算术运算符:+
,-
,*
,/
,%
,-
取负数,~
取反,.
并置,intdiv
向下取整php7+
赋值运算符:=
,+=
,-=
,*=
,/=
,%=
,.=
自增/减运算符:++
,--
比较运算符:==
,===
绝对等于,值相等类型相同,!=
,<>
,!==
,>
,<
,>=
,<=
逻辑运算符:and
,or
,xor
,&&
,||
,!
数组运算符:+
两者集合,==
有相同的键值对,===
有相同的键值对且顺序相同类型相同,!=
,<>
,!==
三元运算符:expr1 ? expr2 : expr3
在php中数组是键值对
php
$arr1 = array("a" => "red", "b" => "green");
$arr2 = array("a" => "red", "c" => "blue");
$arr = $arr1 + $arr2;
var_dump($arr);
echo PHP_EOL;
$arr3 = [1, 2, 3];
var_dump($arr3);
echo PHP_EOL;
运算符优先级
优先级从高到低,具有相同优先级要结合方向决定求值顺序 注:左=从左到右(省略),右=从右到左
clone
,new
,结合方向:无[
++
,--
,(int/float/string/array/object/bool)
,右instanceof
,无!
,右,逻辑运算符*
,/
,%
+
,-
,.
,字符串运算符>>
,<<
,位运算符==
,!=
,<>
,===
,!==
&
,位运算符和引用^
,位运算符|
,位运算符&&
||
?:
=
,+=
,-=
,*=
,/=
,%=
,.=
,&=
,|=
,^=
,>>=
,<<=
,=>
,右,赋值运算符and
xor
or
,
and
与&&
,or
与||
效果一样,优先级不一样
可通过括号来明确运算顺序,而非靠运算符优先级和结合性来决定,通常能增加代码可读性
流程控制
条件语句
if
if else
if elseif else
switch
,case
分支需要break
中断
循环
while
do while
for
foreach
数组
单变量存储多个值的特殊变量
使用array()
来创建
在php中,有3种类型的数组:
- 数值数组:带有数值键的数组,自动/人工分配数值键
- 关联数组:带有指定键的数组,每个键关联一个值
- 多维数组:包含一个或多个数组的数组
数值数组
php
// 数值数组,自动分配数值键
$cars = array("Volvo", "BMW", "Toyota");
echo "I like " . $cars[0] . ", " . $cars[1] . ", " . $cars[2];
// 数值数组,人工分配数值键
$cars2 = array();
$cars2[0] = "LS";
$cars2[2] = "XS";
echo "I like " . $cars2[0] . ", " . $cars2[2];
// 统计数组元素个数
echo count($cars2);
// 遍历数组
$len = count($cars);
for ($i = 0; $i < $len; $i++) {
echo $cars[$i];
echo PHP_EOL;
}
关联数组
php
$age = array("Peter"=>"35", "Bem"=>"37", "Joe"=>"43");
echo $age["Peter"];
$age2 = array();
$age2["Peter"] = "35";
echo $age2["Peter"];
// 遍历
foreach ($age as $key => $value) {
echo "key=" . $key . ", value=" . $value;
echo PHP_EOL;
}
数组排序
sort()
对数组进行升序排列rsort()
对数组进行降序排列asort()
根据关联数组的值对数组进行升序排列arsort()
根据关联数组的值对数组进行降序排列ksort()
根据关联数组的键对数组进行升序排列krsort()
根据关联数组的键对数组进行降序排列
升序排列
php
$cars = array("Volvo", "BMW", "Toyota");
sort($cars);
foreach ($cars as $v) {
echo "value=" . $v;
echo PHP_EOL;
}
降序排列
php
$cars = array("Volvo", "BMW", "Toyota");
rsort($cars);
foreach ($cars as $v) {
echo "value=" . $v;
echo PHP_EOL;
}
根据值升序排列
php
$age = array("Peter"=>"35", "Bem"=>"37", "Joe"=>"43");
asort($age);
foreach ($age as $k => $v) {
echo "key=" . $k . ", value=" . $v;
echo PHP_EOL;
}
根据值降序排列
php
$age = array("Peter"=>"35", "Bem"=>"37", "Joe"=>"43");
arsort($age);
foreach ($age as $k => $v) {
echo "key=" . $k . ", value=" . $v;
echo PHP_EOL;
}
根据键升序排列
php
$age = array("Peter"=>"35", "Bem"=>"37", "Joe"=>"43");
ksort($age);
foreach ($age as $k => $v) {
echo "key=" . $k . ", value=" . $v;
echo PHP_EOL;
}
根据键降序排列
php
$age = array("Peter"=>"35", "Bem"=>"37", "Joe"=>"43");
krsort($age);
foreach ($age as $k => $v) {
echo "key=" . $k . ", value=" . $v;
echo PHP_EOL;
}
函数
php提供了超过1000个的内建函数,也可以自定义函数
函数名以字母或下划线开头,做到见名知意
php不支持函数重载
php
// 函数定义
function hello($name): void
{
echo "Hello $name!";
}
// 函数执行
hello("skye");
函数参数可以设置默认值
php
function hello($name = "skyeeeee"): void
{
echo "Hello $name!";
echo PHP_EOL;
}
hello("skye");
hello();
面向对象
OOP
类的定义
php
class Fruit
{
public $name;
public function getName()
{
return $this->name;
}
public function setName($name): void
{
$this->name = $name;
}
}
对象的创建
php
$apple = new Fruit();
$apple->setName('Apple');
echo $apple->getName();
魔术方法
php把以__
开头的方法称为魔术方法,在php中起着重大作用
类的构造方法 __construct()
php中对象创建后的第一个被对象自动调用的方法,每个类都有一个构造方法,若没有显示声明该方法,则类都会默认存在一个无参无内容的空构造方法
通常被用来执行一些有用的初始化任务,如成员属性赋初始值
php
class Fruit
{
public $name;
function __construct($name) {
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setName($name): void
{
$this->name = $name;
}
}
$apple = new Fruit("Apple");
echo $apple->getName();
类的析构函数 __destruct()
该方法在对象销毁之前被调用,可用来关闭文件、释放结果集等,php5才引入
php
class Fruit
{
public $name;
function __construct($name) {
$this->name = $name;
}
function __destruct()
{
echo "$this->name destruct";
echo PHP_EOL;
}
public function getName()
{
return $this->name;
}
public function setName($name): void
{
$this->name = $name;
}
}
$apple = new Fruit("Apple");
echo $apple->getName();
echo PHP_EOL;
$apple = new Fruit("Banana");
echo $apple->getName();
echo PHP_EOL;
__call()
为了避免调用的方法不存在时产生错误,而意外的导致程序终止,可以使用该方法来避免
该方法会在调用方法不存在时自动调用,程序仍会继续执行下去
php
class Fruit
{
public $name;
function __construct($name) {
$this->name = $name;
}
function __call($funcName, $args)
{
echo "$funcName(".implode(', ', $args).") not found".PHP_EOL;
}
}
$apple = new Fruit("Apple");
$apple->hello("test");
__callStatic()
同__call()
,区别就是调用方法是静态方法还是实例方法
php
class Fruit
{
public $name;
function __construct($name) {
$this->name = $name;
}
static function __callStatic($funcName, $args)
{
echo "static $funcName(".implode(', ', $args).") not found".PHP_EOL;
}
}
Fruit::eat("food");
__get()
类成员变量若是private
时,在类外无法访问,可通过该方法在类外访问,入参是属性名
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __get($propertyName)
{
if ($propertyName == 'age') {
return $this->age;
} else {
return $this->name;
}
}
}
$apple = new Fruit("Apple");
echo $apple->name.PHP_EOL;
echo $apple->age.PHP_EOL; // 不存在__get()方法就会报错
__set()
用来设置私有属性,传递的参数是属性名和值
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __get($propertyName)
{
if ($propertyName == 'age') {
return $this->age;
} else {
return $this->name;
}
}
function __set($propertyName, $value) {
$this->$propertyName = $value;
}
}
$apple = new Fruit("Apple");
echo $apple->age.PHP_EOL; // 不存在__get()方法就会报错
$apple->age=20;
echo $apple->age.PHP_EOL;
__isset()
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __get($propertyName)
{
if ($propertyName == 'age') {
return $this->age;
} else {
return $this->name;
}
}
function __isset($content)
{
echo "当在类外部调用isset()函数测定私有成员{$content}时自动调用".PHP_EOL;
}
}
$apple = new Fruit("Apple");
echo isset($apple->name).PHP_EOL;
echo isset($apple->age).PHP_EOL;
__unset()
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18)
{
$this->name = $name;
$this->age = $age;
}
function __get($propertyName)
{
if ($propertyName == 'age') {
return $this->age;
} else {
return $this->name;
}
}
function __unset($content)
{
echo "当在类外部调用unset()函数删除私有成员{$content}时自动调用,否则会报错" . PHP_EOL;
}
}
$apple = new Fruit("Apple");
unset($apple->name);
unset($apple->age);
__sleep()
当执行serialize()
时会先调用该方法,可用于清理对象并返回一个包含对象中所有应被序列化的变量名称的数组
若该方法未返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误
该方法不能返回父类的私有成员的名字,会产生一个E_NOTICE级别的错误,可以用Serializable接口替代
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __sleep()
{
echo "在外部调用serialize()函数时会先调用__sleep()方法".PHP_EOL;
return array("name", "age");
}
}
$apple = new Fruit("Apple");
echo serialize($apple).PHP_EOL;
__wakeup()
当执行unserialize()
时会先调用该方法
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __sleep()
{
echo "在外部调用serialize()函数时会先调用__sleep()方法".PHP_EOL;
return array("name", "age");
}
function __wakeup()
{
echo "在外部调用unserialize()函数时会先调用__wakeup()方法".PHP_EOL;
return array("name", "age");
}
}
$apple = new Fruit("Apple");
$serialApple = serialize($apple);
echo unserialize($serialApple)->name.PHP_EOL;
__toString()
该方法用于当一个类被用作字符串时该如何回应,必须返回一个字符串
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __toString()
{
return "Fruit[name=".$this->name.", age=".$this->age."]";
}
}
$apple = new Fruit("Apple");
echo $apple.PHP_EOL;
__invoke()
该方法用于把对象看作函数来调用时的回应
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __invoke(): void
{
echo "Object Fruit[name=".$this->name.", age=".$this->age."]";
}
}
$apple = new Fruit("Apple");
$apple();
__clone()
对象复制之前调用
php
class Fruit
{
public $name;
private $age;
function __construct($name, $age = 18) {
$this->name = $name;
$this->age = $age;
}
function __clone(): void
{
echo "Clone Object Fruit[name=".$this->name.", age=".$this->age."]".PHP_EOL;
}
}
$apple = new Fruit("Apple");
$apple2 = clone $apple;
var_dump($apple);
var_dump($apple2);