写点什么

【PHP】英文博客专栏 PHP 快速入门个人笔记

作者:懒时小窝
  • 2023-01-24
    湖南
  • 本文字数:14140 字

    阅读完需:约 46 分钟

引言

​ 本文是对于英文原始博客的一个 PHP 入门专栏的个人笔记摘录,因为非常入门并且自身有 JAVA 语言基础,看的比较快并且会忽略很多共同点,建议读者有能力可以看看博客的原文顺带提升英文能力,作者文字表达能力非常强,写的非常棒。


​ 这篇专栏介绍了 PHP8 入门,专栏写于 2022 年中旬,不管是单词还是语法句式都十分通俗易懂,学技术的同时提升英语水平并且有助于提升自信心

目录

原始博客地址

https://thevalleyofcode.com/php/

介绍

PHP 是一个两级分化的语言,觉得它好的人称赞它简单,PHP 的语法比较自由上手非常简单。而不好的人则会像我一样认为是个四不像语言,既有前端脚本的影子,但是同时支持面向对象的方式组合代码,总是会有种奇怪的感觉。


但是不得不承认,世界上绝大多数 WEB 网站都是 PHP 构建的,PHP 是 web 领域当之无愧的佼佼者。虽然这语言现在在国内是一潭死水,但是在国外它是能排进前十的热门编程语言。


PHP 在短短的几年内快速发展,从最开始几年的 PHP4 和 PHP5 的膨胀,到现在 PHP8 的版本发布,更新迭代的速度还是很快的。

过往历史

PHP 起源于 1994 年的个人博客网站,作者是 rasmus lerdorf,PHP 在 1997 到 2000 随着互联网的快速崛起并且爆炸式增长。


用途:


  • 和 HTML 存在一点点交互动态的 HTML 语言,以及 web 应用程序当中对外提供访问。

  • Facebook 就是构建在 PHP 网站之上的,早期微微博也同样用的 PHP 语言

  • wiki 百科同样使用 PHP 构建

PHP 是一个怎么样的语言

虽然 PHP 被戏称脚本语言,但是实际上它是解释型语言,和广大编译运行的服务端语言没什么区别。只不过和其他大部分解释型语言不同点是 PHP 不需要编译就可以运行,或者可以认为编译的动作本身就是自动的。这和 Java,GO 以及 c 语言等等都有很大不同。在 JAVA 领域 PHP 非常像 JSP,但是实际对比会发现要比 JSP 更灵活和方便,也更好用。


这个语言内部可自动通过编译器把代码翻译成机器可以认识以及可以运行的语言。


从个人角度看 PHP 被称作脚本语言是比较合适的词,因为它在 web 领域如鱼得水。此外因为 PHP 是动态类型语言,开发者不需要关注变量类型,但是有时候又因为类型转化的问题出现一些难以察觉的错误。


动态类型语言是高级编程语言的趋势这一点毋庸置疑。就连 JDK11 也实现了 var 关键词的动态类型语法糖定义就可以看出端倪。


最后用作者的原文总结:PHP 是一门很像 JavaScript 的语言,不同的是它有动态类型,灵活类型的解释型后端语言。

设置 PHP

本部分作者介绍了 mamp 的安装使用,个人没有使用经验就不详细记录了,对于 PHP 作者推荐使用 VScode 编辑器开发,个人使用下来发现确实好用,当然 Jerbrian 的 PHP IDE 也不错,对于常年使用 IDEA 的开发人员基本可以无缝衔接。


PHP 开发一般依赖套件,PHP 本身就是起源于个人博客专职于 WEB Application 领域,所以他需要最为根本的软件比如 Apach,MysqlRedis 等等。


PHP 开源套件软件很多,这里就不过多展开了。当然套件开发不是强制的,当然开发者开发过程中也可以单独部署中间件和数据库。


对于 php 的 web 应用,必备组件无外乎下面几个:


  • PHP 语言环境变量,推荐最新版的 PHP8。

  • 数据库,通常以 MySQL 为主。

  • apache 或者 nignix 作为 web 服务器。


PHP 是面向 http web 应用程序开发语言,很多时候都需要和 HTML 页面配合,这和古老的 JSP 语言有点类似,但是实际使用的时候更多是和模板引擎以及框架配合。

第一个 PHP 程序

PHP 的 Helloworld 非常简单,只需要在 mamp 或者其他 PHP 程序的开发软件根目录创建index.html的文件即可。很多 web server 服务器基本都使用 index.html 作为默认的访问页面,所以如果直接访问 localhost 端口的 webserver 根路径,那么就会展示对应index.html页面。


PHP 代码通常以及<?php开头以及?>结尾,中间编写有关 PHP 语言代码即可,我们可以在index.html文件全文替换成下面的代码。


<?phpecho 'World';?>
复制代码


虽然访问的是 html 页面,但是里面的 PHP 代码却会被识别翻译并且执行。

基本类型

PHP 是动态类型语言,定义变量方式如下:


<?php$a = 5;$b = '444';
?>
复制代码


PHP 支持下面的基础类型:


  • bool boolean values (true/false)

  • int integer numbers (no decimals)

  • float floating-point numbers (decimals)

  • string strings

  • array arrays

  • object objects

  • null a value that means “no value assigned”


如果要知道变量的数据类型,可以使用var_dump()的方法检查:


$age = 20;
var_dump($age);
复制代码

操作符

PHP 的基础操作符:


算数操作: +, -, *, / (division), % (remainder) and ** (exponential).


赋值操作:=


比较操作:<, >, <=, >=,此外还有相等和全等操作,含义和 JS 的类似,相等可以类型不匹配比如 5=='5',全等类型必须一致,比如 5==='5'就是 false。


  • == returns true if the two operands are equal.

  • === returns true if the two operands are identical.


和比较操作相反的有!==以及!=符号。


自增操作:++和 - - 操作。


特殊符号:think new lines \n or tabs \t


拼接操作:PHP 和其他语言比较大的区别,那就是类似字符串拼接用的是 “.”


$fullName = $firstName . ' ' . $lastName;
复制代码

字符串操作

字符串的操作和其他后端语言类似,下面简单列举博客中的一些实验,这里直接上代码就不过多解释了:


$name = 'Flavio';strlen($name); //6
$name = 'Flavio';substr($name, 3); //"vio" - start at position 3, get all the restsubstr($name, 2, 2); //"av" - start at position 2, get 2 items
$name = 'Flavio';str_replace('avio', 'ower', $name); //"Flower"
$name = 'Flavio';$itemObserved = str_replace('avio', 'ower', $name); //"Flower"
复制代码


  • trim() strips white space at the beginning and end of a string

  • strtoupper() makes a string uppercase

  • strtolower() makes a string lowercase

  • ucfirst() makes the first character uppercase

  • strpos() finds the firsts occurrence of a substring in the string

  • explode() to split a string into an array

  • implode() to join array elements in a string

编写注释

编写注释的方法如下:


// single comment/*
this is a comment
*/
//or
/* * * this is a comment * */
//or to comment out a portion of code inside a line:
/* this is a comment */
复制代码

和数字有关的内置函数

作者事先列举一些和数字或者数学计算有关函数:


  • round() to round a decimal number, up/down depending if the value is > 0.5 or smaller

  • ceil() to round a a decimal number up

  • floor() to round a decimal number down

  • rand() generates a random integer

  • min() finds the lowest number in the numbers passed as arguments

  • max() finds the highest number in the numbers passed as arguments

  • is_nan() returns true if the number is not a number

Array 数组

数组定义可以用方括号或者 array 函数,数组可以当做其他编程语言的列表(容器)看待,不需要定义长度并且容量自动增长。


列表里面的元素类型可以不一致,甚至元素可以是另一个列表。


// 数组定义$list = [];
$list = array();
// 初始化定义$list = [1, 2];
$list = array(1, 2);
$list = ['a', 'b'];$list[0]; //'a' --the index starts at 0$list[1]; //'b'
$list = [1, [2, 'test']];
复制代码


添加元素可以使用空方括号的方式设置值,这时候参数会自动在末尾追加。


$list = ['a', 'b'];$list[] = 'c';
/*$list == [ "a", "b", "c",]*/
复制代码


使用 array_unshift 添加元素到列表头部:


$list = ['b', 'c'];array_unshift($list, 'a');
/*$list == [ "a", "b", "c",]*/
复制代码


使用 count 函数计算数组的元素数量:


$list = ['a', 'b'];
count($list); //2
复制代码


检查元素是否在数组,使用 in_array 函数`:


$list = ['a', 'b'];
in_array('b', $list); //true
复制代码

arrays 常用函数

常用函数根据作者笔记记录即可。


  • is_array() to check if a variable is an array

  • array_unique() to remove duplicate values from an array

  • array_search() to search a value in the array and returns the key

  • array_reverse() to reverse an array

  • array_reduce() to reduce an array to a single value using a callback function

  • array_map() to apply a callback function to each item in the array. Typically used to create a new array by modifying the values of an existing array, without altering that.

  • array_filter() to filter an array to a single value using a callback function

  • max() to get the maximum value contained in the array

  • min() to get the minimum value contained in the array

  • array_rand() to get a random item from the array

  • array_count_values() to count all the values in the array

  • implode() to turn an array into a string

  • array_pop() to remove the last item of the array and return its value

  • array_shift() same as array_pop() but removes the first item instead of the last

  • sort() to sort an array

  • rsort() to sort an array in reversing order

  • array_walk() similarly to array_map() does something for every item in the array, but in addition it can change values in the existing array


关联数组

到目前为止,我们已经使用了带有增量数字索引的数组:0、1、2... 您还可以使用带有命名索引(键)的数组,我们称它们为关联数组:


$list = ['first' => 'a', 'second' => 'b'];
$list['first'] //'a'$list['second'] //'b'
复制代码


可以通过关联数组进行标记 key 以及 value,关联数组同样有比较多的操作方法:


  • array_key_exists() to check if a key exists in the array

  • array_keys() to get all the keys from the array

  • array_values() to get all the values from the array

  • asort() to sort an associative array by value

  • arsort() to sort an associative array in descending order by value

  • ksort() to sort an associative array by key

  • krsort() to sort an associative array in descending order by key


在此处查看所有有关联数组函数: https://www.php.net/manual/en/ref.array.php

条件语句

条件语句的最基础用法:


$age = 17;
if ($age > 18) { echo 'You can enter the pub';} else { echo 'You cannot enter the pub';}
复制代码


这里用了 cannot 而不是 can't 是因为单引号嵌套会出现“截断”导致报错,需要单引号内部嵌套需要使用转义符\反斜杠


<, >, <=, >=, ==, === , !=, !== 这些符号在实际使用和条件语句一起使用:


这里需要注意 PHP 提供了专门的 elseif,而不能像其他语言一样使用 else[空格]if 的语法:


$age = 17;
if ($age > 20) { echo 'You are 20+';} elseif ($age > 18) { echo 'You are 18+';} else { echo 'You are <18';}
复制代码


Swtich 的语法和其他编程语言是一致的:


$age = 17
switch($age) { case 15: echo 'You are 15'; break; case 16: echo 'You are 16'; break; case 17: echo 'You are 17'; break; case 18: echo 'You are 18'; break; default: echo "You are $age";}
复制代码

循环

PHP 的循环语句语法有while, do while, for, and foreachwhiledo while的方法和大部分编程语言没什么不同。


$counter = 0;
while ($counter < 10) { echo $counter; $counter++;}

$counter = 0;
do { echo $counter; $counter++;} while ($counter < 10);



复制代码


主要差别是foreach语法,可以用他遍历列表,也可以用来遍历列表获取索引,也就遍历关联数组的key/value值。


$list = ['a', 'b', 'c'];
foreach ($list as $value) { echo $value;}
$list = ['a', 'b', 'c'];
foreach ($list as $key => $value) { echo $key;}
复制代码


对于普通 for 循环,可以使用 count 函数计算数组长度的 size。


$list = ['a', 'b', 'c'];
for ($i = 0; $i < count($list); $i++) { echo $list[$i];}
//result: abc
复制代码


和循环搭配使用的 break 和 continue 语法:


$list = ['a', 'b', 'c'];
for ($i = 0; $i < count($list); $i++) { if ($list[$i] == 'b') { break; } echo $list[$i];}// result a
$list = ['a', 'b', 'c'];
for ($i = 0; $i < count($list); $i++) { if ($list[$i] == 'b') { continue; } echo $list[$i];}
//result: ac
复制代码

函数

PHP 函数的主要特点:


  • PHP 的函数只支持单返回值。

  • 如果没有返回值或者省略则接收为 null,注意这里是有陷阱的,如果调用一个无返回值的方法,会获得 null 的结果,PHP 并不会对此报错。

  • 参数可以等号设置默认值。

  • 可以指定参数类型,也可以省略,省略会自动根据上下文猜测类型。


function sendEmail($to) {  echo "send an email to $to";}
sendEmail('test@test.com');
// result: send an email to test@test.com
复制代码


可以手动指定参数的类型,当然绝大多数情况下不会这样写(很啰嗦还浪费时间),所以看一下就可以直接忘记:


function sendEmail(string $to, string $subject, string $body) {  //...}
复制代码


PHP 函数的参数支持定义的时候指定默认值,如果调用方没有传值就使用默认值:


function sendEmail($to, $subject = 'test', $body = 'test') {  //...}
sendEmail('test@test.com')
复制代码


带返回值的函数定义如下,我们同样可以手动指定函数的返回值类型:


function sendEmail($to): bool {  return true;}
function sendEmail($to) { return true;}
$success = sendEmail('test@test.com');
if ($success) { echo 'email sent successfully';} else { echo 'error sending the email';}
复制代码

匿名函数

PHP 的匿名函数和 JavaScript 的写法是类似的,使用变量接收不带名字的function方法,由于不带返回值的函数默认返回 Null,所以可以认为匿名函数的变量就是 Null。


匿名函数是支持变量传递的,语法是在匿名方法后面追加 use 括号


$test = 'test';
$myfunction = function() use ($test) { echo $test; return 'ok';};
$myfunction()
复制代码

值传递和地址传递

PHP 默认情况下的参数传递都是值传递,也就是说外部的参数传递在函数内部出现改变是不会一并改变的,因为值传递是用了一份变量副本进行数据操作。


地址传递或者说引用传递需要在参数前面加取地址的符号,这里的写法就类似 C 语言的指针了。


$character = 'a';
function test(&$c) { $c = 'b';}
test($character);
echo $character; //'b'
复制代码

箭头函数

PHP 的箭头函数相当于 JS 的函数式编程,和 Java 的箭头函数类似,但是箭头函数用了等号而已。


$printTest = fn() => 'test';
$printTest(); //'test'
$multiply = fn($a, $b) => $a * $b;
$multiply(2, 4) //8
复制代码


前面提到过匿名函数需要使用 use 语句接收外部参数,而箭头函数就不需要如此定义便可以直接接收外部参数,写法方便和简洁易懂:


$a = 2;$b = 4;
$multiply = fn() => $a * $b;
$multiply()
复制代码


总之 PHP 的函数有三种定义方法,普通函数,箭头函数和匿名函数。

使用 map,reduce,filter 函数循环数组处理

array_map:函数可以对于每个元素调用回调函数并且返回结果,最后会返回一个全新的列表。首个参数是回调函数,其次是列表。


array_filter:函数则是对于每个元素调用回调函数并且过滤掉不符合的元素,注意第一个参数是数组,然后第二个参数是回调函数,filter 是符合函数回调结果的可以认为是有效的。


array_reduce:函数比较特殊一些,最后有一个参数有一个初始值,函数会从初始化的值对后续的每个元素进行回调函数合并,比如计算阶乘的值就可以用这个函数。


$numbers = [1, 2, 3, 4];$doubles = array_map(fn($value) => $value * 2, $numbers);
//$doubles is now [2, 4, 6, 8]
$numbers = [1, 2, 3, 4];$even = array_filter($numbers, fn($value) => $value % 2 === 0)
//$even is now [2, 4]
$numbers = [1, 2, 3, 4];
$result = array_reduce($numbers, fn($carry, $value) => $carry * $value, 1)
复制代码

面向对象

面向对象讨论

PHP 的面向对象和 JAVA 的比较相似,可以说大部分语法都可以通用。

如何构建对象

构建对象在 PHP 当中也是使用 new 的方式,可以通过 new 构建多个对象,但是对象名称不能重复。

属性和方法

属性和方法常常配合使用,这里一并介绍魔术方法构造参数。方法可以指定构造函数 __construction,其中可以添加初始化对象的行为,PHP 当中对象有很多内置函数都以 双下划线开头。


class Dog {  public $name;
public function __construct($name) { $this->name = $name; }
public function bark() { echo $this->name . ' barked!'; }}
$roger = new Dog('Roger');$roger->bark();
复制代码


每个类默认有一个不执行任何工作的空构造器,重写之后如果无空构造函数,需要传入指定参数才能初始化,否则会出现 PHP 的 error 异常。


class Dog {  public string $name;
public function __construct($name) { $this->name = $name; }
public function bark() { echo $this->name . ' barked!'; }}
$roger = new Dog('Roger');$roger->name; //'Roger'$roger->bark(); //'Roger barked!'
// resultTypeError: Dog::__construct():Argument #1 ($name) must be of type int,string given on line 14
复制代码


对象属性在 PHP 中存在三个限定符号,可以手动指定下面三个级别:


protected
private
public
复制代码


这几个类别分别对应了继承对象可见,私有,对外公开,和 JAVA、Python 语言类似,这里就不过多扩展含义和更多用法案例了。


class Dog {  public $name;  public $age;  public $color;}
$roger = new Dog();
$roger->name = 'Roger';$roger->age = 10;$roger->color = 'gray';
var_dump($roger);
/*object(Dog)#1 (3) { ["name"]=> string(5) "Roger" ["age"]=> int(10) ["color"]=> string(4) "gray"}*/
复制代码


如果需要外部访问,多数情况建议用 get 和 set 的方式,对于类内部的属性首先需要定义 public,其次引用需要使用 this→xxx 的方式,注意这个 this 是不能省略的,也是和 JAVA 差别比较大的点,而外部则为对象的变量引用设置的名称加上→符号,比如 dog→bark()


$roger = new Dog('Roger');$roger->name; //'Roger'$roger->bark(); //'Roger barked!'
复制代码


属性只有在 public 修饰符描述的情况下才能对外访问和修改,如果为 private 或者 protected 则不行,限定符的安全访问和 Java 的没什么区别。


方法内部的 $this 比较特殊,代表当前对象本身引用,和后端编程语言 JAVA 等类似。

继承

PHP 的对象支持继承,具体语法如下:


class Dog extends Animal {
}
$roger = new Dog();$roger->eat();
复制代码

重写

PHP 重写和 JAVA 的规则类似,所以我们按照 JAVA 的对象继承理解即可:


class Animal {  public $age;
public function eat() { echo 'the animal is eating'; }}
class Dog extends Animal { public function eat() { echo 'the dog is eating'; }}
复制代码

静态

静态方法和静态属性都是在属性或者方法名称前面加 static。对于 static 类或者对象内部使用 self 来定义,引用方式为两个冒号,比如 User::getName


User::getName 标识静态变量的写法是强制规定的,否则编译器会报错Undefined variable '$version'.intelephense(1008)


class Utils {  public static $version = '1.0';}// 静态常量的对象内部引用self::$version;// 静态常量的外部引用class Utils {  public static function version() {    return '1.0';  }}Utils::version
复制代码

对象比较

前面的操作符提到过双等号和三等号有不同的含义,对于大部分情况下对象的比较=====会返回 true 和 false,下面的例子就是很好的解释。


class Dog {  public $name = 'Good dog';}
$roger = new Dog();$syd = new Dog();
echo $roger == $syd; //true
echo $roger === $syd; //false
复制代码

对象遍历

对象遍历通常是遍历所有的内部属性值,可以使用关联循环的写法,这个对象遍历是 PHP 的一些语法特性,算是比较有意思的东西。


class Dog {  public $name = 'Good dog';  public $age = 10;  public $color = 'gray';}
$dog = new Dog();
foreach ($dog as $key => $value) { echo $key . ': ' . $value . '<br>';}
复制代码

对象克隆

PHP 的clone 方法和 JAVA 一样属于浅拷贝,深入拷贝需要额外编写一些代码。


class Dog {  public $name;}
$roger = new Dog();$roger->name = 'Roger';
$syd = clone $roger;
复制代码

魔术方法

魔术方法可以理解为 PHP 为了方便开发者管理对象而提供的一些”切面“,开发者可以通过重写对象的特定方法控制行为:


class Dog {  public $name;
public function __clone() { $this->cloned = true; }}
$roger = new Dog();$roger->name = 'Roger';
$syd = clone $roger;echo $syd->cloned;
复制代码


其他的魔术方法包含:__call(), __get(), __set(), __isset(), __toString()

文件包含

文件包含的操作在 PHP 中有四种写法:include, include_once, require, require_once.


include loads the content of another PHP file, using a relative path.

require does the same, but if there’s any error doing so, the program halts. include will only generate a warning.


“include”:使用相对路径加载另一个 PHP 文档的内容。


“require”:执行相同的操作,但如果载入有任何错误进程将停止。注意“include”只会生成警告,require 会直接抛出异常信息。


include_oncerequire_once在没有_once的情况下执行与其相应函数相同的操作,但它们额外确保在进程执行期间仅包含一次文件。


按照作者的经验法则是经验法则永远不要使用包含或要求,因为您可能会加载同一个文档 2 次,include_once 和 require_once 帮助您避免此问题。


下面介绍文件包含的相关操作:


require_once('test.php');
//now we have access to the functions, classes//and variables defined in the `test.php` file
require_once('../test.php');require_once('test/test.php');require_once('/var/www/test/file.php');
复制代码

文档系统的有用常量、函数和变量

有关文件的魔法常量:


__FILE__
复制代码


还有一个和服务器有关的全局常量:


$_SERVER['SCRIPT_FILENAME']
复制代码


除此之外其他的一些常用常量或者函数:


getcwd():内置函数__DIR__:另一个神奇常量将__FILE__与 dirname() 组合以获得
当前文档夹的完整路径:dirname(__FILE__)使用 $_SERVER[“DOCUMENT_ROOT”]
复制代码

错误

PHP 的错误或者说异常信息分为下面三类:


  • Warnings

  • Notices

  • Errors


前面两个错误都是警告类似的,虽然有可能在程序运行过程中会出现问题但是不影响程序运行,而最后一个 error 则是会由 PHP 的解释器直接返回报错信息。


默认情况下 PHP 是不展示错误信息的,我们可以修改`php.ini`的配置进行调整。为了更快的了解配置文件的位置和相关信息,我们可以使用 phpinfo()方法和查看:


<?phpphpinfo();?>
复制代码



原作者案例的对应的路径为:/Applications/MAMP/bin/php/php8.1.0/conf/php.ini,默认情况下为 off,意味着错误将不再显示在网站中,但在这种情况下将在 MAMP(如果是别的开发脚手架则为其他的路径) 的 logs 文档夹的 php_error.log 文档中看到它们。


个人的 wampServer 的对应错误日志信息如下:



我们可以指定错误日志重定向到特定的目录:


; Log errors to specified file. PHP's default behavior is to leave this value; empty.; http://php.net/error-log; Example:;error_log = php_errors.log
复制代码


添加错误信息可以通过方法 error_log('test');处理,下面截取框架的用法:


 /**     * Logs user information to webserver logs.     *     * @param string $user   user name     * @param string $status status message     *     * @return void     */    public static function logUser($user, $status = 'ok')    {        if (function_exists('apache_note')) {            apache_note('userID', $user);            apache_note('userStatus', $status);        }        /* Do not log successful authentications */        if (! $GLOBALS['PMA_Config']->get('AuthLogSuccess') && $status == 'ok') {            return;        }        $log_file = self::getLogDestination();        if (empty($log_file)) {            return;        }        $message = self::getLogMessage($user, $status);        if ($log_file == 'syslog') {            if (function_exists('syslog')) {                @openlog('phpMyAdmin', LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);                @syslog(LOG_WARNING, $message);                closelog();            }        } elseif ($log_file == 'php') {            @error_log($message);        } elseif ($log_file == 'sapi') {            @error_log($message, 4);        } else {            @error_log(                date('M d H:i:s') . ' phpmyadmin: ' . $message . "\n",                3, $log_file            );        }    }
复制代码

异常

异常通常是除开编程语言语法之外的可控错误,PHP 和 JAVA 一样使用了try{...}catch(Exception $e)的方式进行处理:


try {  //do something} catch (Throwable $e) {//we can do something here if an exception happens  echo $e->getMessage();}
复制代码


实验中我们可以使用除 0 的异常检查异常信息的打印:


echo 1 / 0;
复制代码



异常处理的原则是细分不同的具体异常给出不同的提示,PHP 的异常捕获规则和 JAVA 一致:


try {  echo 1 / 0;} catch (DivisionByZeroError $e) {  echo 'Ooops I divided by zero!';} catch (Throwable $e) {  echo $e->getMessage();}
复制代码


PHP 同样支持 finally 的写法:


try {  echo 1 / 0;} catch (DivisionByZeroError $e) {  echo 'Ooops I divided by zero!';} catch (Throwable $e) {  echo $e->getMessage();} finally {  echo ' ...done!';}
复制代码


更多异常处理可以参考下面的网站:


https://www.php.net/manual/en/reserved.exceptions.php

日期

常量和枚举

我们可以在 PHP 中使用 define() 内置函数定义常量,使用语法如下:


define('TEST', 'some value');
复制代码


这种常量定义在使用的时候不需要使用 $符号:


define('TEST', 'some value');
echo TEST;
复制代码


define 类似 C 语言的 typeof。


其他定义常量的方法是 const:


const BREED = 'Siberian Husky';
复制代码


第三种定义常量的方法是定义枚举:


enum Status {  case EATING;  case SLEEPING;  case RUNNING;}
复制代码


枚举常量的使用方法如下:


class Dog {  public Status $status;}
$dog = new Dog();
$dog->status = Status::RUNNING;
if ($dog->status == Status::SLEEPING) { //...}
复制代码

PHP web 平台部署

PHP 是一种服务器端语言,通常以 2 种方式使用。


  1. 第一种方法是类似 JSP 一样在 HTML 中嵌入 PHP 后端语言代码达到动态数据展示的效果。

  2. 第二种是 PHP 更像是负责生成“应用进程”的引擎,模板语言来生成 HTML,并且所有内容都由我们所谓的框架管理。(推荐)

处理 HTTP 请求

本部分介绍了在没有任何框架的情况下如何接收和处理 HTTP 请求,我们可以在 webroot 的路径创建一个 test.php 文件,此时如果对于脚手架配置伪静态,可以直接通过/test 访问。


WEB 应用绝大部分都是 POST 和 GET 请求,PHP 提供了$_GET, $_POST and $_REQUEST 这些方法


_ GET 对象访问所有查询字符串数据,该对象称为超全局,并在我们所有的 PHP 文档中自动可用。$_ POST:对于 POST、PUT 和 DELETE 请求,更有可能需要以urlencoding 数据的形式发布的数据或使用 FormData 对象,PHP 使用 $_POST 为您提供该对象。_ REQUEST 囊括了上面两个魔法常量的内容。


下面的案例介绍了有关这些魔法常量的用法


 if (isset($_GET['tables'])) {    $constrains = $GLOBALS['dbi']->getForeignKeyConstrains(        $_REQUEST['db'],        $_GET['tables']    );    $response = Response::getInstance();    $response->addJSON('foreignKeyConstrains',$constrains);}
复制代码

使用 cookies$_SEVER 对象

$_SERVER 包含了许多非常有用的服务器信息,我们可以使用 Phpinfo 方法获取服务器内容:


<?phpphpinfo();?>
复制代码



下面是基本用法:


  • $_SERVER['HTTP_HOST']

  • $_SERVER['HTTP_USER_AGENT']

  • $_SERVER['SERVER_NAME']

  • $_SERVER['SERVER_ADDR']

  • $_SERVER['SERVER_PORT']

  • $_SERVER['DOCUMENT_ROOT']

  • $_SERVER['REQUEST_URI']

  • $_SERVER['SCRIPT_NAME']

  • $_SERVER['REMOTE_ADDR']


$_GET 方法的使用案例如下:


<form>  <input type="text" name="name" />  <input type="submit" /></form>
<?phpif (isset($_GET['name'])) { echo '<p>The name is ' . $_GET['name'];}?>
复制代码


$_POST 方法的使用案例如下:


<form **method="POST"**>  <input type="text" name="name" />  <input type="submit" /></form>
<?phpif (isset($_POST['name'])) { echo '<p>The name is ' . $_POST['name'];}?>
复制代码


这些内容直接使用的情况比较少,通常在框架中可以看到类似的引用。

使用 cookies

PHP 通过$_COOKIE变量可以获取到所有和 Cookie 有关的信息。


if (isset($_COOKIE['name'])) {  $name = $_COOKIE['name'];}
复制代码


setcookie() 方法可以设置 cookie 信息,我们可以添加第三个参数来说明 cookie 何时过期。如果省略,Cookie 将在会话结束时/浏览器关闭时过期。


setcookie('name', 'Flavio');
复制代码


比如下面的代码可以设置 7 天之后过期:


setcookie('name', 'Flavio', time() + 3600 * 24 * 7);
复制代码


我们只能在 Cookie 中存储有限数量的数据,用户在清除浏览器数据时可以在客户端清除 Cookie。下面是 Cookie 使用的一些简单例子:


<?phpif (isset($_POST['name'])) {  setcookie('name', $_POST['name']);}if (isset($_POST['name'])) {  echo '<p>Hello ' . $_POST['name'];} else {  if (isset($_COOKIE['name'])) {    echo '<p>Hello ' . $_COOKIE['name'];  }}?>
<form method="POST"> <input type="text" name="name" /> <input type="submit" /></form>
复制代码

Sessions

Cookie 的一个非常有趣的用例是基于 cookie 的会话。


<?phpsession_start();?>
复制代码


你会发现访问对应文件之后,你将会看到一个新 cookie 名称(PHPSESSID)被定义。这个 ID 就是我们常说的 session ID



与我们使用 cookie 的方式类似,我们现在可以使用 $_SESSION 来存储用户发送的信息,但这次它不存储在客户端。只有 PHPSESSID 会被存储到客户端。


<?phpsession_start();
if (isset($_POST['name'])) { $_SESSION['name'] = $_POST['name'];}if (isset($_POST['name'])) { echo '<p>Hello ' . $_POST['name'];} else { if (isset($_SESSION['name'])) { echo '<p>Hello ' . $_SESSION['name']; }}?>
<form method="POST"> <input type="text" name="name" /> <input type="submit" /></form>
复制代码



可以使用session_unset()方法删除 Session 当中的信息,如果需要移除 session 的 cookie 信息,可以使用下面的方法:


setcookie(session_name(), '');
复制代码

IO

PHP 服务端访问可以使用下面的方法:


文件是否存在file_exists()


file_exists('test.txt') //true
复制代码


文件大小获取:


filesize('test.txt')
复制代码


PHP 的文件读写使用同一个方法,不同的是提供访问参数使用了 读模式和写模式:


$file = fopen('test.txt', 'r')
复制代码


上面的方法为只读模式,同时提供描述信息作为返回值。我们可以调用 fclose($fd) 终止文件读写。


下面是把文件内容读取到变量的方法,这里吐槽一下使用要比 JAVA 的套版代码简单很多,也比较符合新生高级编程语言的设计思路。


$file = fopen('test.txt', 'r')
fread($file, filesize('test.txt'));
//or
while (!feof($file)) { $data .= fgets($file, 5000);}
复制代码


注意:feof() 检查我们是否尚未到达文档末尾,因为 fgets 一次读取 5000 字节


逐行扫描文件套版代码:


$file = fopen('test.txt', 'r')
while(!feof($file)) { $line = fgets($file); //do something}
复制代码


要写入文件,必须一开始打开文件的时候指定写入模式,同时配合fwrite函数以及fclose形成完整的文件读写。


$data = 'test';$file = fopen('test.txt', 'w')fwrite($file, $data);fclose($file);
复制代码


删除文件的方法如下:


unlink('test.txt')
复制代码


更多文件读写方法参考:https://www.php.net/manual/en/ref.filesystem.php

database

所有后端语言必备的东西,这里列举了几个常用的 database:



绝大多数情况如果你需要一个数据库,你应该使用框架或 ORM,这将节省 SQL 注入的安全问题,比如比较常见的Laravel’s Eloquent 框架。

JSON

JSON 是一种可移植的数据格式,我们用于表示数据并将数据从客户端发送到服务器。PHP 提供了下面两个常用方法来实现 JSON 字符串和对象之间的转化:


  • json_encode() to encode a variable into JSON

  • json_decode() to decode a JSON string into a data type (object, array…)


下面是一些简单使用例子:


$test = ['a', 'b', 'c'];
$encoded = json_encode($test); // "["a","b","c"]" (a string)
$decoded = json_decode($encoded); // [ "a", "b", "c" ] (an array)
复制代码

email

发送邮件可以使用下面的方法:


mail('test@test.com', 'this subject', 'the body');
复制代码


https://github.com/PHPMailer/PHPMailer 提供了更多有邮件相关的实用 API。

部署 PHP 应用 Composer

Composer 类似 NodeJS 的 NPM,和大部分的一站式依赖管理是类似的。Composer 安装之后的页面内容如下:



可以使用composer require nesbot/carbon 命令对于项目进行依赖导入。正确导入之后会出现composer.json以及composer.lock文件,composer.lock文件可以对于依赖版本进行锁定。


{    "require": {        "nesbot/carbon": "^2.58"    }}
复制代码


当对应目录引入依赖之后,在 PHP 文件当中可以使用下面的用法:


<?phprequire 'vendor/autoload.php';
use Carbon\Carbon;
echo Carbon::now();
复制代码


最终访问对应页面的展示内容如下:



“require 'vendor/autoload.php';”行作用是启用自动加载。这里顺带提一下还记得我们谈论 require_once()和 include_once()吗?我们不需要手动搜索要包含的文档,我们只需使用 use 关键字将库导入我们的代码即可。

部署 PHP 应用

最后作者写了一篇从零开始搭建 GIT 的文章比较有意思,本部分内容建议结合一些框架项目学习,博客提到的内容比较入门这里就不记录了。


See how to setup Git and GitHub from zero

写在最后

更多的当作英文学习资料看待,顺带能学到一些技术内容,挺不错的。


发布于: 刚刚阅读数: 3
用户头像

懒时小窝

关注

赐他一块白石,石头上写着新名 2020-09-23 加入

如果我们想要知道自己想要做什么,必须先找到自己的白色石头。欢迎关注个人公众号“懒时小窝”,不传播焦虑,只分享和思考有价值的内容。

评论

发布
暂无评论
【PHP】英文博客专栏PHP快速入门个人笔记_php_懒时小窝_InfoQ写作社区