这一章主要对PHP基础语法进行学习,篇幅可能过长。php
html
由于语法实在太多,没办法所有覆盖讲解。我这里语法的这一部分,适合了解一些编程语言的人看。做为快速入门。java
这里假设你已经具有一门其余编程语言的基本知识。若是你是彻底的编程新手,建议你去PHP官网系统的学习这部份内容。c++
语法简单,开发速度快,效率高,学习成本低。github
简单但功能强大,很是适合web网站开发。golang
服务端脚本语言运行速度快,无需编译。web
跨平台能力强。shell
面向对象的语言。编程
弱类型,动态类型语言。
没有main入口。
具备访问域关键字。
多线程语言。
多继承语言。
__halt_compiler() | abstract | and | array() | as |
---|---|---|---|---|
break | callable (as of PHP 5.4) | case | catch | class |
clone | const | continue | declare | default |
die() | do | echo | else | elseif |
empty() | enddeclare | endfor | endforeach | endif |
endswitch | endwhile | eval() | exit() | extends |
final | finally (从PHP 5.5开始) | for | foreach | function |
global | goto (从PHP 5.3开始) | if | implements | include |
include_once | instanceof | insteadof (从PHP 5.4开始) | interface | isset() |
list() | namespace (从PHP 5.3开始) | new | or | |
private | protected | public | require | require_once |
return | static | switch | throw | trait (从PHP 5.4开始) |
try | unset() | use | var | while |
xor | yield (从PHP 5.5开始) |
CLASS | DIR (从PHP 5.3开始) | FILE | FUNCTION | LINE | METHOD |
---|---|---|---|---|---|
NAMESPACE (从PHP 5.3开始) | TRAIT (从PHP 5.4开始) |
有时也被称为魔术常量,是PHP预约义的常量。不区分大小写。
和Node.js中的__dirname
、__filename
概念相同。使用方式:__常量名__
PHP 基本用法有两种,第一种是写在单独的PHP文件中,第二种是写在html文件中。
php文件中的写法是第一行以<?php
开头便可。
<?php
echo "hello";
若是是嵌套在html文件中,使用<?php ?>
这种写法,写过JSP的同窗应该知道,这和<% %>
做用几乎同样。
<h1>
PHP没有在行尾补充分号的机制,因此代码的每一行,咱们都须要添加分号 ;
PHP 中变量、常量、函数等都遵循相同的规则。
一个有效的变量名由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。即字母 a-z,A-Z,以及 ASCII 字符从 127 到 255(0x7f-0xff)。
PHP社区喜欢使用下划线命名法,而不是驼峰命名法。虽然这种风格看上去很别扭,但咱们仍是尽可能遵照吧。
$dog_name = "little white";// good
$catName = "big black";// bad
经常使用的有两个,echo 和 print。区别不大,echo 更经常使用一些,你能够一直使用echo。
echo能够输出多个字符串到页面上,print只能输出一个。
echo没有返回值,运行更快。print返回值老是1。
<?php
$dog_name = "little white";
$cat_name = "big black";
echo '<div>' ,$dog_name, '</div>';
print $cat_name;
PHP支持3种注释,分别借鉴了C、C++和shell的注释。
// c语言风格注释
/* c++风格注释 */
# shell风格注释
PHP 中的变量用一个美圆符号后面跟变量名来表示。变量名是区分大小写的。
<?php
$a = 123;
echo $a;
要注意一点,变量的声明和使用,始终都须要带着美圆符号$
符号。
PHP变量做用域有4种。
local
global
static
parameter
本地变量的做用域,好比在函数中,用完即清理掉。
在全部函数以外定义的变量,拥有全局做用域。
全局变量能够在除了函数外任何地方使用。在函数内使用须要加global关键字。
全局变量被手机在一个叫作 $GLOBALS 的数组里面,也能够经过 $GLOBALS['name']的方式访问,但不推荐这么些。
将local变量持久保存。
参数做用域。
<?php
$x = 1;// global做用域
function add($num/* parameter做用域 */)
{
static $z = 0;// static做用域,用于记录add函数被调用的次数。add运行结束后,$z仍然存在,但没法再访问到。
$z++;
global $x;// 使用global必须使用global关键字
$y = 2;// local做用域,最普通的本地变量,每次add函数运行结束,被清理掉,再次运行再次建立。
return $x + $y + $z + $num;
// 另外一种访问 global 变量的方法
// return $GLOBALS['x'] + $y + $z + $num;
}
echo add(1);// 5 (1+2+1+1)
echo add(2);// 7 (1+2+2+2)
echo add(3);// 9 (1+2+3+3)
定义一个常量,须要使用define函数。
define有3个参数。常量名、常量值、是否大小写敏感。前两个必选,第三个可选参数默认false,对大小写不敏感。设置成true,就对大小写敏感。
<?php
// 大小写敏感
define('tiger', "i'm tiger");
echo tiger;
// 大小写不敏感
define('Dog', "i'm dog", true);
echo '<div> doG </div>';
string 字符串
boolean 布尔值
integer 整型
float(double) 浮点型/双精度
<?php
$str = "hello";
$int = 123;
$float = 1.2;
$bool = true;
array 数组
使用array函数建立,也可使用字面量形式[]建立
<?php
$arr = array('1', 2, 3.0);
$arr2 = ['1', 2, 3.0];
object 对象
须要经过new关键字来建立。
callable 可调用
其实本质就是函数
resource 资源
NULL 无类型
var_dump 函数,查看变量内容
gettype 函数,调试时使用,返回字符串类型
is_type 函数,检验类型,返回boolean值
<?php
$arr = array("1", 2, 3.0);
echo var_dump($arr);// 输出array(3) { [0]=> string(1) "1" [1]=> int(2) [2]=> float(3) }
echo "<br/>";
echo gettype($arr);// 输出 array
echo "<br/>";
echo is_array($arr);// 输出1,实际上是boolean值true,可是会被转换成1输出到页面
强制类型转换 语法类同 java
settype函数
<?php
// 将 int 类型转换成 string类型
$one = 1;
(string)$one;// 强制类型转换,变量前面加(类型)
settype($one, "string");// settype函数转换,接受2个参数
这一部分涉及内容过多,但和其余大部分编程语言相似,我只把运算符当在这里,进行补充说明。不会详细解读。
例子 | 名称 | 结果 |
---|---|---|
-$a | 取反 | $a 的负值。 |
$a + $b | 加法 | $a 和 $b 的和。 |
$a - $b | 减法 | $a 和 $b 的差。 |
$a * $b | 乘法 | $a 和 $b 的积。 |
$a / $b | 除法 | $a 除以 $b 的商。 |
$a % $b | 取模 | $a 除以 $b 的余数。 |
$a ** $b | Exponentiation | Result of raising $a to the $b'th power. Introduced in PHP 5.6. |
例子 | 名称 | 结果 |
---|---|---|
$a & $b | And(按位与) | 将把 $a 和 $b 中都为 1 的位设为 1。 |
$a | $b | Or(按位或) | 将把 $a 和 $b 中任何一个为 1 的位设为 1。 |
$a ^ $b | Xor(按位异或) | 将把 $a 和 $b 中一个为 1 另外一个为 0 的位设为 1。 |
~ $a | Not(按位取反) | 将 $a 中为 0 的位设为 1,反之亦然。 |
$a << $b | Shift left(左移) | 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。 |
$a >> $b | Shift right(右移) | 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。 |
例子 | 名称 | 结果 |
---|---|---|
$a == $b | 等于 | TRUE,若是类型转换后 $a 等于 $b。 |
$a === $b | 全等 | TRUE,若是 $a 等于 $b,而且它们的类型也相同。 |
$a != $b | 不等 | TRUE,若是类型转换后 $a 不等于 $b。 |
$a <> $b | 不等 | TRUE,若是类型转换后 $a 不等于 $b。 |
$a !== $b | 不全等 | TRUE,若是 $a 不等于 $b,或者它们的类型不一样。 |
$a < $b | 小与 | TRUE,若是 $a 严格小于 $b。 |
$a > $b | 大于 | TRUE,若是 $a 严格大于 $b。 |
$a <= $b | 小于等于 | TRUE,若是 $a 小于或者等于 $b。 |
$a >= $b | 大于等于 | TRUE,若是 $a 大于或者等于 $b。 |
$a <=> $b | 太空船运算符(组合比较符) | 当$a小于、等于、大于$b时 分别返回一个小于、等于、大于0的integer 值。 PHP7开始提供. |
$a ?? $b ?? $c | NULL 合并操做符 | 从左往右第一个存在且不为 NULL 的操做数。若是都没有定义且不为 NULL,则返回 NULL。PHP7开始提供。 |
++$a | 前加 | $a 的值加一,而后返回 $a。 |
---|---|---|
$a++ | 后加 | 返回 $a,而后将 $a 的值加一。 |
--$a | 前减 | $a 的值减一, 而后返回 $a。 |
$a-- | 后减 | 返回 $a,而后将 $a 的值减一。 |
例子 | 名称 | 结果 |
---|---|---|
$a and $b | And(逻辑与) | TRUE,若是 $a 和 $b 都为 TRUE。 |
$a or $b | Or(逻辑或) | TRUE,若是 $a 或 $b 任一为 TRUE。 |
$a xor $b | Xor(逻辑异或) | TRUE,若是 $a 或 $b 任一为 TRUE,但不一样时是。 |
! $a | Not(逻辑非) | TRUE,若是 $a 不为 TRUE。 |
$a && $b | And(逻辑与) | TRUE,若是 $a 和 $b 都为 TRUE。 |
$a || $b | Or(逻辑或) | TRUE,若是 $a 或 $b 任一为 TRUE |
@当将其放置在一个 PHP 表达式以前,该表达式可能产生的任何错误信息都被忽略掉。
`` PHP 将尝试将反引号中的内容做为 shell 命令来执行,并将其输出信息返回。能够利用执行运算符对操做系统进行直接接触。
链接运算符(“.”) 返回其左右参数链接后的字符串
链接赋值运算符(“.=”),它将右边参数附加到左边的参数以后
例子 | 名称 | 结果 |
---|---|---|
$a + $b | 联合 | $a 和 $b 的联合。 |
$a == $b | 相等 | 若是 $a 和 $b 具备相同的键/值对则为 TRUE。 |
$a === $b | 全等 | 若是 $a 和 $b 具备相同的键/值对而且顺序和类型都相同则为 TRUE。 |
$a != $b | 不等 | 若是 $a 不等于 $b 则为 TRUE。 |
$a <> $b | 不等 | 若是 $a 不等于 $b 则为 TRUE。 |
$a !== $b | 不全等 | 若是 $a 不全等于 $b 则为 TRUE。 |
instanceof
PHP的流程控制和其余语言相似。比较简单,有如下几种:
判断:if 和 else 及 elseif/else if
循环:while、do-while、for、foreach
跳出/中断循环:break、continue
switch和case
declare
返回:return
导入:require/include和require once
跳转:goto
这里主要讲一下 declare 、 require/include 、 goto,它们比较特殊。而其余流程控制关键字比较简单也比较常见,几乎在全部语言中都有相似概念。
require的概念能够理解为引包。和JavaScript中的require很像,更相似于Java中的import。
假设有这样一个目录结构
在utils.php 中写一个函数
<?php
function my_log($message)
{
echo '<div>'.$message.'</div>';
}
咱们想在其余地方复用,那么就是用require便可。好比index.php
<?php
require('utils.php');
echo my_log('hi.');
include的用途与require是彻底同样的,你能够尝试将index.php中的require替换为include。
它们的区别主要在于错误处理方式的不一样以及返回值的不一样。
require出错会中断程序,抛出致命错误。
include出错不会中断程序,抛出警告错误。
最佳实践是将它们放置在文件的最顶部。
include_once和require_once的做用是防止屡次导入,若是在程序中其余地方导入过相同的文件,就不会再次导入。
主要做用:每执行n行低级代码,就会执行一遍注册的函数。
除此以外,还能够开启严格模式和定义源本件编码。
语法:只有一个参数是ticks = n,通常会配合register_tick_function()使用。
<?php
// 每执行3行低级代码会触发一次 yell 函数
declare(ticks = 3);
function yell(){
echo '<h1>wangwang</h1>';
}
register_tick_function('yell');
// 注册后,什么都不作,yell 函数也会执行1遍
// for 是高级代码,不会算入
for($i = 0; $i < 10; $i++)
{
$i;// 访问 $i 属于低级语法,会计算
}
跳转到程序中的另外一位置。
goto容易让程序难以理解,相似于golang中的go。不建议使用。
<?php
a:
echo 'a';
goto c;
b:
echo 'b';
c:
echo 'c';
goto会跳转到标记为c的位置,页面会输出ac。而直接跳过goto和c之间的代码段。这样就致使程序不会按照从上到下逐行执行。
PHP命名空间与Java的分包,ES6的模块化概念相似。
主要做用是防止自定义的类、函数或常量名称重复。
用法:使用关键字namespace 声明命名空间,使用 use 关键字使用其余空间常量/函数/类。
一个文件能够有多个命名空间。可使用正常语法,也可使用大括号语法,更推荐大括号的语法。
命名空间应该是在PHP代码的最顶部出现,也就是程序的第一句。
PHP支持子命名空间。
<?php
// 声明一个命名空间 Animal
namespace Animal {
// 命名空间中有一个Dog类
class Dog
{
}
}
// 另外一个命名空间 Main
namespace Main{
// 使用 此空间之外空间的常量/函数/类时,须要用 use 关键字
use Animal\Dog;
new Dog();
}
用 function 来自定义函数
PHP 中的全部函数和类都具备全局做用域,能够定义在一个函数以内而在以外调用,反之亦然。
PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。
<?php
function func($name = "f"/* 若是不传参数,name默认就是f */, ...$option/* 默认是数组,能够接受多个参数,最后转换成数组 */)
{
echo '<h1>',$name,'</h1>';
echo '<h1>',var_dump($option),'</h1>';
}
func();
PHP里面全部的参数都是按值传递的。
<?php
$arr = array('1', '2');
function func($arr_p)
{
$arr_p['3'] = '3';
echo '<h1>', var_dump($arr_p), '</h1>';
}
func($arr);
echo var_dump($arr);
若是是写JavaScript的同窗,可能会认为输出的两个对象应该是一个内存块的数据对吧?但在PHP中不是这样的。
输出结果为:
array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [3]=> string(1) "3" }
array(2) { [0]=> string(1) "1" [1]=> string(1) "2" }
也就是说$arr_p['3'] = '3';
这行代码并无改变global中的arr变量,若是你想直接改变原来的变量内容,这时就须要使用按引用传递。
只须要在参数前面加一个&符号,这样就会把参数的指针传递进去,而后在函数内部访问arr_p变量时,就会寻址到全局变量arr的内存地址。
function func(&$arr_p)
这时的输出结果就符合预期了。
能够进行参数类型声明,这样能够限制函数的使用方式。
但在默认状况下,php会强制转化指望的类型。
能够开启严格类型,这样会抛出TypeError。惟一例外是integere传给float。
function func(array $arr_p)
函数省略return,返回值为NULL。
能够返回任意类型。
只能有一个返回值。
返回值也能够有类型声明,和golang语法同样,在参数后面添加:type。
function func(array $arr_p):string{}// 返回值指定string类型
但注意,这个写法只支持PHP7之后的版本。
若是一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,而且尝试执行它。
$func('args')
也能够用可变函数的语法来调用一个对象的方法。
当调用静态方法时,函数调用要比静态属性优先。
<?php
$func = function () {
echo 'hi';
};
$func();
PHP 有不少标准的函数和结构。
可是须要PHP扩展模块编译支持。
不安装模块,直接使用内置函数会致使function is undefined 异常
也叫闭包函数,容许 临时建立一个没有指定名称的函数。最常常用做回调函数参数的值。
闭包函数也能够做为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。
相似于JavaScript中的var func = function (){}的形式
使用var定义,默认为共有。
在类的成员里面,访问类的非静态属性使用->,访问静态属性使用::
使用const声明。访问常量时不须要$。
__construct。具备构造函数的类会在每次建立新对象时先调用此方法,因此很是适合在使用对象以前作一些初始化工做。
__destruct
析构函数会在到某个对象的全部引用都被删除或者当对象被显式销毁时执行。
若是子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,须要在子类的构造函数中调用 parent::__construct()。若是子类没有定义构造函数则会如同一个普通的类方法同样从父类继承。
要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()
和 Java 语言同样:有关键字 public(公有),protected(受保护)或 private(私有)
被定义为公有的类成员能够在任何地方被访问。被定义为受保护的类成员则能够被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所在的类访问。
类属性必须定义为公有,受保护,私有之一。若是用 var 定义,则被视为公有。
方法和属性相同。
<?php
class Animal
{
// var $name;// 和下面那句声明彻底相同
public function __construct($name)
{// 构造函数,new 调用时最早执行
$this->name = $name;
}
public function __destruct()
{// 析构函数,new 调用时,生命周期的最后一步
echo '建立实例成功';
}
public $name;// 这个是公有的,能够在实例中访问
private $age;// 私有的,仅在 Animal 内能够访问
const category = 'Animal';// 常量
public function getCategory(): string
{
return category;// 访问常量不须要$
}
public function eat(): string
{
return $this->name . 'eat';
}
}
$dog = new Animal('dog');
我比较承认golang团队的观点,继承是面向对象语言设计中比较失败的一个概念。对于类的扩展,组合要比继承好得多。
使用关键字 extends 来继承,子类会覆盖父类的方法。和Java的继承基本上没什么差异,这里不讲了。
PHP的接口与其余面向对象编程语言无异。
接口是面向对象很是重要的概念,其本质就是一种约定。
约定了类应该具备哪些特征。但接口不会作具体实现。
一个类能够实现多个接口,用逗号隔开。
将上面的例子改造一下:
<?php
// 定义了一个IAnimal接口,里面要求实现两个共有方法,getCategory和eat。
interface IAnimal{
public function getCategory();
public function eat($food);
}
// implement关键字来实现接口
class Animal implements IAnimal
{
public function __construct($name)
{
$this->name = $name;
}
public function __destruct()
{
echo '建立实例成功';
}
public $name;
private $age;
const category = 'Animal';
public function getCategory()
{
return category;
}
public
function eat($food): string
{
return $this->name.'eat'.$food;
}
}
new Animal('dog');
PSR是PHP Standard Recommendations(PHP标准推荐)的简称,这个是php-fig组织制定的一套规范。至今,php-fig已经发布了五个规范。
这一点上,PHP作的仍是很好的,有一个统一的标准,比Java和JavaScript强。
这里咱们只须要看PSR-2就行了,大约有这么几个方面。
代码必须使用4个空格符而不是 tab键 进行缩进。
每行的字符数应该软性保持在80个以内, 理论上必定不可多于120个, 但必定不能有硬性限制。
每一个 namespace
命名空间声明语句和 use
声明语句块后面,必须插入一个空白行。
类的开始花括号({
)必须写在函数声明后自成一行,结束花括号(}
)也必须写在函数主体后自成一行。
方法的开始花括号({
)必须写在函数声明后自成一行,结束花括号(}
)也必须写在函数主体后自成一行。
类的属性和方法必须添加访问修饰符(private
、protected
以及 public
), abstract
以及 final
必须声明在访问修饰符以前,而 static
必须声明在访问修饰符以后。
控制结构的关键字后必须要有一个空格符,而调用方法或函数时则必定不能有。
控制结构的开始花括号({
)必须写在声明的同一行,而结束花括号(}
)必须写在主体后自成一行。
控制结构的开始左括号后和结束右括号前,都必定不能有空格符。
简单学习了PHP基本语法和代码风格,为后续PHP学习奠基基础。