? ? ? ? 为什么要起这个名字?其实其中回答了何种人适合看这篇文章——有其他语言基础刚入web后端的初学者。本文主要是对菜鸟教程中的PHP部分做了精简,有基础的能节省不少时间。
PHP变量的作用域
- local
- global:在函数内调用函数外的全局变量时会用到,存储在一个名为 $GLOBALS[index] 的数组中。
- static:希望某个局部变量不要被删除时用到,该变量仍然是函数的局部变量
- parameter
echo 和 print
? ? ? ? php原生只有这两种输出模式,它们的区别如下:
- echo - 可以输出一个或多个字符串(比较快)
- print - 只允许输出一个字符串,返回值总为 1
? ? ? ? 此外,还有如下常用的输出方式:
- print_r -?打印关于变量的易于理解的信息,如果给出的是 string、integer 或 float,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。 记住,print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
- var_dump -?显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。var_dump 返回表达式的类型与值而 print_r 仅返回结果,相比调试代码使用 var_dump 更便于阅读。
PHP类型比较
字符串的内置函数总结
- strlen() -?函数返回字符串的长度(字节数)strlen("Hello world!");
- strpos() -?在字符串内查找一个字符或一段指定的文本?strpos("Hello?world!","world")
- 更多详细函数
运算符补充
在 PHP7+ 版本多了一个 NULL 合并运算符???,实例如下:
<?php
// 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值
$username = $_GET['user'] ?? 'nobody';
// 类似的三元运算符
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
PHP7+ 支持组合比较符(combined comparison operator)也称之为太空船操作符,符号为?<=>。组合比较运算符可以轻松实现两个变量的比较,当然不仅限于数值类数据的比较。
语法格式如下:
$c = $a <=> $b;
- 如果?$a > $b, 则?$c?的值为?1。
- 如果?$a == $b, 则?$c?的值为?0。
- 如果?$a < $b, 则?$c?的值为?-1。
数组排序函数
- sort() - 对数组进行升序排列
- rsort() - 对数组进行降序排列
- asort() - 根据关联数组的值,对数组进行升序排列
- ksort() - 根据关联数组的键,对数组进行升序排列
- arsort() - 根据关联数组的值,对数组进行降序排列
- krsort() - 根据关联数组的键,对数组进行降序排列
超级全局变量
$GLOBALS
????????包含了全部变量的全局组合数组。变量的名字就是数组的键。
$_SERVER
????????包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。
元素/代码 | 描述 |
---|
$_SERVER['PHP_SELF'] | 当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /test.php/foo.bar。__FILE__ 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。 | $_SERVER['GATEWAY_INTERFACE'] | 服务器使用的 CGI 规范的版本;例如,"CGI/1.1"。 | $_SERVER['SERVER_ADDR'] | 当前运行脚本所在的服务器的 IP 地址。 | $_SERVER['SERVER_NAME'] | 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.runoob.com) | $_SERVER['SERVER_SOFTWARE'] | 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24) | $_SERVER['SERVER_PROTOCOL'] | 请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。 | $_SERVER['REQUEST_METHOD'] | 访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。 | $_SERVER['REQUEST_TIME'] | 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496) | $_SERVER['QUERY_STRING'] | query string(查询字符串),如果有的话,通过它进行页面访问。 | $_SERVER['HTTP_ACCEPT'] | 当前请求头中 Accept: 项的内容,如果存在的话。 | $_SERVER['HTTP_ACCEPT_CHARSET'] | 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:"iso-8859-1,*,utf-8"。 | $_SERVER['HTTP_HOST'] | 当前请求头中 Host: 项的内容,如果存在的话。 | $_SERVER['HTTP_REFERER'] | 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。) | $_SERVER['HTTPS'] | 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。 | $_SERVER['REMOTE_ADDR'] | 浏览当前页面的用户的 IP 地址。 | $_SERVER['REMOTE_HOST'] | 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。 | $_SERVER['REMOTE_PORT'] | 用户机器上连接到 Web 服务器所使用的端口号。 | $_SERVER['SCRIPT_FILENAME'] | 当前执行脚本的绝对路径。 | $_SERVER['SERVER_ADMIN'] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@runoob.com) | $_SERVER['SERVER_PORT'] | Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。 | $_SERVER['SERVER_SIGNATURE'] | 包含了服务器版本和虚拟主机名的字符串。 | $_SERVER['PATH_TRANSLATED'] | 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 | $_SERVER['SCRIPT_NAME'] | 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。 | $_SERVER['SCRIPT_URI'] | URI 用来指定要访问的页面。例如 "/index.html"。 |
$_REQUEST
????????收集HTML表单提交的数据。当用户通过点击 "Submit" 按钮提交表单数据时, 表单数据将发送至<form>标签中 action 属性中指定的脚本文件。 在这个实例中,我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据,你可以修改该指定的脚本文件名。 然后,我们可以使用超级全局变量 $_REQUEST 来收集表单中的 input 字段数据:
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_REQUEST['fname'];
echo $name;
?>
</body>
</html>
?$_POST
????????收集表单数据,在HTML form标签的指定该属性:"method="post"。当用户通过点击 "Submit" 按钮提交表单数据时, 表单数据将发送至<form>标签中 action 属性中指定的脚本文件。 在这个实例中,我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据,你可以修改该指定的脚本文件名。 然后,我们可以使用超级全局变量 $_POST 来收集表单中的 input 字段数据:
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_POST['fname'];
echo $name;
?>
</body>
</html>
$_GET
????????应用于收集表单数据,在HTML form标签的指定该属性:"method="get"。$_GET 也可以收集URL中发送的数据。假定我们有一个包含参数的超链接HTML页面:
<html>
<body>
<a href="test_get.php?subject=PHP&web=runoob.com">Test $GET</a>
</body>
</html>
????????当用户点击链接 "Test $GET", 参数 "subject" 和 "web" 将发送至"test_get.php",你可以在 "test_get.php" 文件中使用 $_GET 变量来获取这些数据。以下实例显示了 "test_get.php" 文件的代码:
<html>
<body>
<?php
echo "Study " . $_GET['subject'] . " @ " . $_GET['web'];
?>
</body>
</html>
总结
????????关于get和post方法,下面有两篇文章总结,建议没事多看看,增强理解:
命名空间
????????在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。
子命名空间
????????与目录和文件的关系很像,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义:
<?php
namespace MyProject\Sub\Level; //声明分层次的单个命名空间
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */ }
?>
????????上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。
命名空间使用
- 非限定名称,或不包含前缀的类名称(就是啥前缀也没有,被解析成当前命名空间,类似文件名)
- 限定名称,或包含前缀的名称(不以“/”开头,完整的命名空间得和当前的命名空间组合,类似相对路径)
- 完全限定名称,或包含了全局前缀操作符的名称(以“/”开头,命名空间是完整的,类似绝对路径)
- 下面给个例子
<?php
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() {}
class foo
{
static function staticmethod() {}
}
?>
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* 非限定名称 */
foo(); // 解析为函数 Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo ,方法为 staticmethod
echo FOO; // 解析为常量 Foo\Bar\FOO
/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
// 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>
使用命名空间:别名/导入
????????使用use操作符导入/使用别名
// 第一种使用方式
namespace foo;
use My\Full\Classname as Another;
// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;
// 第二种使用方式
use My\Full\Classname as Another, My\Full\NSname;
// 第三种使用方式
use My\Full\Classname as Another, My\Full\NSname;
$a = 'Another';
$obj = new $a; // 实际化一个 Another 对象
面向对象
????????PHP 不支持多继承
构造函数
void __construct ([ mixed $args [, $... ]] )
析构函数
void __destruct ( void )
接口
? ? ? ? 接口定义示例:
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
? ? ? ? 另外。PHP的面向对象包括:抽象类、static、final等,与Java或其他的语言一致。
包含文件
????????include 和 require 语句用于在执行流中插入写在其他文件中的有用的代码。
????????include 和 require 除了处理错误的方式不同之外,在其他方面都是相同的:
- require 生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会停止执行。
- include 生成一个警告(E_WARNING),在错误发生后脚本会继续执行。
- require 一般放在 PHP 文件的最前面,程序在执行前就会先导入要引用的文件;
- include 一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程。
Cookie
创建Cookie
????????setcookie() 函数用于设置 cookie。setcookie() 函数必须位于 <html> 标签之前。参数如下:
setcookie(name, value, expire, path, domain);
取回 Cookie
????????PHP 的 $_COOKIE 变量用于取回 cookie 的值。可以通过isset() 函数来确认是否已设置了 cookie,示例如下:
<?php
if (isset($_COOKIE["user"]))
echo "欢迎 " . $_COOKIE["user"] . "!<br>";
else
echo "普通访客!<br>";
?>
?删除Cookie
????????当删除 cookie 时,您应当使过期日期变更为过去的时间点。示例如下:
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>
Session
????????PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置。Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的。
????????在计算机上操作某个应用程序时,打开它,做些更改,然后关闭它。这很像一次对话(Session)。计算机知道您是谁。它清楚您在何时打开和关闭应用程序。然而,在因特网上问题出现了:由于 HTTP 地址无法保持状态,Web 服务器并不知道您是谁以及您做了什么。
????????PHP session 解决了这个问题,它通过在服务器上存储用户信息以便随后使用(比如用户名称、购买商品等)。然而,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久存储信息,可以把数据存储在数据库中。
????????Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。
启动Session
????????在您把用户信息存储到 PHP session 中之前,首先必须启动会话。session_start() 函数必须位于 <html> 标签之前,示例如下:
<?php session_start(); ?>
<html>
<body>
</body>
</html>
????????存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:
<?php
session_start();
// 存储 session 数据
$_SESSION['views']=1;
?>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<?php
// 检索 session 数据
echo "浏览量:". $_SESSION['views'];
?>
</body>
</html>
清除Session
????????unset() 函数用于释放指定的 session 变量:
<?php
session_start();
if(isset($_SESSION['views']))
{
unset($_SESSION['views']);
}
?>
????????可以通过调用 session_destroy() 函数彻底销毁 session。
邮件发送
????????PHP mail() 函数用于从脚本中发送电子邮件。PHP 运行邮件函数需要一个已安装且正在运行的邮件系统(如:sendmail、postfix、qmail等)。所用的程序通过在 php.ini 文件中的配置设置进行定义。函数的使用方式与参数说明如下:
mail(to,subject,message,headers,parameters)
参数 | 描述 |
---|
to | 必需。规定 email 接收者。 | subject | 必需。规定 email 的主题。注释:该参数不能包含任何新行字符。 | message | 必需。定义要发送的消息。应使用 LF (\n) 来分隔各行。每行应该限制在 70 个字符内。 | headers | 可选。规定附加的标题,比如 From、Cc 和 Bcc。应当使用 CRLF (\r\n) 分隔附加的标题。 | parameters | 可选。对邮件发送程序规定额外的参数。 |
错误处理
????????在 PHP 中,默认的错误处理很简单。一条错误消息会被发送到浏览器,这条消息带有文件名、行号以及描述错误的消息。?使用 die(string) 函数能在浏览器中输出string并结束脚本处理。
创建自定义错误处理器
error_function(error_level,error_message, error_file,error_line,error_context)
参数 | 描述 |
---|
error_level | 必需。为用户定义的错误规定错误报告级别。必须是一个数字。参见下面的表格:错误报告级别。 | error_message | 必需。为用户定义的错误规定错误消息。 | error_file | 可选。规定错误发生的文件名。 | error_line | 可选。规定错误发生的行号。 | error_context | 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。 |
?错误报告级别
????????这些错误报告级别是用户自定义的错误处理程序处理的不同类型的错误:
值 | 常量 | 描述 |
---|
2 | E_WARNING | 非致命的 run-time 错误。不暂停脚本执行。 | 8 | E_NOTICE | run-time 通知。在脚本发现可能有错误时发生,但也可能在脚本正常运行时发生。 | 256 | E_USER_ERROR | 致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。 | 512 | E_USER_WARNING | 非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。 | 1024 | E_USER_NOTICE | 用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。 | 4096 | E_RECOVERABLE_ERROR | 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler()) | 8191 | E_ALL | 所有错误和警告。(在 PHP 5.4 中,E_STRICT 成为 E_ALL 的一部分) |
? ? ? ? ?定义错误处理函数:
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br>";
echo "脚本结束";
die();
}
?设置错误处理程序
????????PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。
????????可以修改错误处理程序,使其仅应用到某些错误,这样脚本就能以不同的方式来处理不同的错误。然而,在本例中,我们打算针对所有错误来使用我们自定义的错误处理程序:
set_error_handler("customError");
触发错误
????????在脚本中用户输入数据的位置,当用户的输入无效时触发错误是很有用的。在 PHP 中,这个任务由 trigger_error() 函数完成。示例代码:
<?php
$test=2;
if ($test>1)
{
trigger_error("变量值必须小于等于 1");
}
?>
? ? ? ? trigger_error()函数有第二个参数,能规定所触发的错误类型。
- E_USER_ERROR - 致命的用户生成的 run-time 错误。错误无法恢复。脚本执行被中断。
- E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
- E_USER_NOTICE - 默认。用户生成的 run-time 通知。在脚本发现可能有错误时发生,但也可能在脚本正常运行时发生。
异常处理
Try、throw 和 catch
????????适当的处理异常代码应该包括:
- Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
- Throw - 里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"。
- Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象。
? ? ? ? 示例代码:
<?php
class customException extends Exception
{
public function errorMessage()
{
// 错误信息
$errorMsg = '错误行号 '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> 不是一个合法的 E-Mail 地址';
return $errorMsg;
}
}
$email = "someone@example.com";
try
{
// 检测邮箱
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
// 如果是个不合法的邮箱地址,抛出异常
throw new customException($email);
}
// 检测 "example" 是否在邮箱地址中
if(strpos($email, "example") !== FALSE)
{
throw new Exception("$email 是 example 邮箱");
}
}
catch (customException $e)
{
echo $e->errorMessage();
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
重新抛出异常
? ? ? ? 当异常被抛出时,希望用不同标准对它的处理:
<?php
class customException extends Exception
{
public function errorMessage()
{
// 错误信息
$errorMsg = $this->getMessage().' 不是一个合法的 E-Mail 地址。';
return $errorMsg;
}
}
$email = "someone@example.com";
try
{
try
{
// 检测 "example" 是否在邮箱地址中
if(strpos($email, "example") !== FALSE)
{
// 如果是个不合法的邮箱地址,抛出异常
throw new Exception($email);
}
}
catch(Exception $e)
{
// 重新抛出异常
throw new customException($email);
}
}
catch (customException $e)
{
// 显示自定义信息
echo $e->errorMessage();
}
?>
设置顶层异常处理器
????????set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。示例代码如下:
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>
异常的规则
- 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
- 每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
- 使用多个 catch 代码块可以捕获不同种类的异常。
- 可以在 try 代码块内的 catch 代码块中抛出(再次抛出)异常。
????????简而言之:如果抛出了异常,就必须捕获它。
过滤器
? ? ? ? PHP过滤器能对外部数据进行验证和过滤,确保能获得正常的数据输入。这里的外部数据主要包括:
- 来自表单的输入数据
- Cookies
- Web services data
- 服务器变量
- 数据库查询结果
? ? ? ? 过滤器主要是通过各种过滤函数实现的,参考函数如下:PHP Filter 函数,这里给出一个示例:
<?php
$int = 123;
if(!filter_var($int, FILTER_VALIDATE_INT))
{
echo("不是一个合法的整数");
}
else
{
echo("是个合法的整数");
}
?>
JSON扩展
? ? ? ? PHP中内置了对JSON对象的编码和解码,常用的函数如下:
函数 | 描述 |
---|
json_encode | 对变量进行 JSON 编码 | json_decode | 对 JSON 格式的字符串进行解码,转换为 PHP 变量 | json_last_error | 返回最后发生的错误 |
|