[TOC]
PHP 基础教程
入门
输出 echo
1 |
|
注释
1 |
|
在 PHP 中,所有用户定义的函数、类和关键词(例如 if、else、echo 等等)都对大小写不敏感。
在 PHP 中,所有变量都对大小写敏感。
支持中文
1 | header("Content-type: text/plain"); |
库文件、或者一些class文件等只有纯php代码的文件不推荐加结束标签
但是如果和 HTML 结合,不加结束标签的话会报错(PHP无法执行HTML代码)。
变量
以 $ 符号开头,其余规则同C语言
PHP 没有创建变量的命令,变量会在首次为其赋值时被创建
函数之外声明的变量拥有 Global 作用域,只能在函数以外进行访问,函数内不能访问。
函数内部声明的变量拥有 LOCAL 作用域,只能在函数内部进行访问。
global 关键词用于访问函数内的全局变量,在(函数内部)变量前面使用 global 关键词:
1 |
|
全局变量
PHP 同时在名为 $GLOBALS[index] 的数组中存储了所有的全局变量。下标存有变量名。这个数组在函数内也可以访问,并能够用于直接更新全局变量。
上面的例子也可以这样写:
1 | function myTest() { |
echo - 能够输出一个以上的字符串
print - 只能输出一个字符串,并始终返回 1
echo 是一个语言结构,有无括号均可使用:echo 或 echo()
1 | $cars=array("Volvo","BMW","SAAB"); |
宏定义 define
1 | define("username", "OK"); |
数据类型
同C系语言(但是不用声明类型,直接使用)
三种格式规定整数:十进制、十六进制(前缀是 0x)或八进制(前缀是 0)
浮点数是有小数点或指数形式的数字。
其余:略
PHP对象:class(类)
1 |
|
可以通过把值设置为 NULL,将变量清空。
字符串
strlen
1 | echo strlen("Hello world!"); //12 字符串长度 |
strpos
1 | echo strpos("Hello world!","world"); //6 字符串检索,位置从0开始,没找到则返回false |
stripos 不区分大小写寻找
注:由于strpos查找开头字符返回值为 0,且 false 的值也是 0,所以判断是否失败要用 ===
1 | if (strpos("Hello", "h") === false) echo "查找失败"; |
str_replace
1 | $s = str_replace("原字符", "新字符", $str); |
正则表达式
正则替换
1 | $s = preg_replace("/原文本/", "新文本", $str); |
正则匹配
1 | $pat = "/待匹配文本/iU"; // i 忽略大小写, U 禁止贪婪匹配 |
字符串中变量
用单引号括住的输出,并没有解析字符串变量,而使用双引号括住的输出,则解析了变量了,输出变量的值。
效率问题
普遍认为,在不需要变量解析的字符串输出,用单引号速度可能会快一些。
字符串中的表达式
用花括号括起来 ${$row[0]}
常量
设置常量,使用 define() 函数。
三个参数:变量名,值,大小写不敏感(默认false,即区分大小写)
1 |
|
1 | var_dump(x) // 输出类型以及数值 |
rand() 随机数
1 | rand(min, max); |
如果没有确定 min 和 max ,rand() 将返回 0 到 RAND_MAX 之间的随机数
编码
ord() 函数:字符转ASCII
chr() 函数:ASCII转字符
PHP 运算符:同C系
包括==、=+-*/%、+=、>=、++自增 等
=== 完全相等,包括键值对的顺序相同类型相同
!== 不全等
!=和<>不等于
. 串接: $txt1 = “Hello” $txt2 = $txt1 . “ world!” 现在 $txt2 包含 “Hello world!”
.= 串接赋值: $txt1 = “Hello” $txt1 .= “ world!” 现在 $txt1 包含 “Hello world!”and && 与
or || 或
xor 异或
! 非if…else… 同C系语言
switch()…同C系语言(同样有case、break、default等),但是支持字符串
while(), do…while, for(;;)… 同C系语言
1 |
|
foreach语句
1 | foreach ($array as $value) { |
函数(函数名对大小写不敏感)
1 | function 函数名($参数) { 代码; } |
可选参数
1 | function 函数名($参数=默认值) { return 返回值; } |
可变参数
1 | function seize() |
数组
三种数组类型
- 索引数组 - 带有数字索引的数组
- 关联数组 - 带有指定键的数组
- 多维数组 - 包含一个或多个数组的数组
1 | $cars=array("Volvo","BMW","SAAB"); |
1 | count(数组名) 数组长度 |
1 | $age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43"); // 关联数组 |
foreach 遍历
1 | foreach($age as $x=>$x_value) { |
数组排序函数
- sort() - 以升序对数组排序
- rsort() - 以降序对数组排序
- asort() - 根据值,以升序对关联数组进行排序
- ksort() - 根据键,以升序对关联数组进行排序
- arsort() - 根据值,以降序对关联数组进行排序
- krsort() - 根据键,以降序对关联数组进行排序
超全局变量
$GLOBALS
- $GLOBALS
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。
变量的名字就是数组的键。
1 |
|
$_SERVER
保存关于报头、路径和脚本位置的信息。
1 |
|
元素/代码 描述
- $_SERVER[‘PHP_SELF’] 返回当前执行脚本的文件名。
- $_SERVER[‘GATEWAY_INTERFACE’]返回服务器使用的 CGI 规范的版本。
- $_SERVER[‘SERVER_ADDR’]返回当前运行脚本所在的服务器的 IP 地址。
- $_SERVER[‘SERVER_NAME’]返回当前运行脚本所在的服务器的主机名(比如 www.w3school.com.cn)。
- $_SERVER[‘SERVER_SOFTWARE’]返回服务器标识字符串(比如 Apache/2.2.24)。
- $_SERVER[‘SERVER_PROTOCOL’]返回请求页面时通信协议的名称和版本(例如,“HTTP/1.0”)。
- $_SERVER[‘REQUEST_METHOD’]返回访问页面使用的请求方法(例如 POST)。
- $_SERVER[‘REQUEST_TIME’]返回请求开始时的时间戳(例如 1577687494)。
- $_SERVER[‘QUERY_STRING’]返回查询字符串,如果是通过查询字符串访问此页面。
- $_SERVER[‘HTTP_ACCEPT’]返回来自当前请求的请求头。
- $_SERVER[‘HTTP_ACCEPT_CHARSET’]返回来自当前请求的 Accept_Charset 头( 例如 utf-8,ISO-8859-1)
- $_SERVER[‘HTTP_HOST’]返回来自当前请求的 Host 头。
- $_SERVER[‘HTTP_REFERER’]返回当前页面的完整 URL(不可靠,因为不是所有用户代理都支持)。
- $_SERVER[‘HTTPS’]是否通过安全 HTTP 协议查询脚本。
- $_SERVER[‘REMOTE_ADDR’]返回浏览当前页面的用户的 IP 地址。
- $_SERVER[‘REMOTE_HOST’]返回浏览当前页面的用户的主机名。
- $_SERVER[‘REMOTE_PORT’]返回用户机器上连接到 Web 服务器所使用的端口号。
- $_SERVER[‘SCRIPT_FILENAME’]返回当前执行脚本的绝对路径。
- $_SERVER[‘SERVER_ADMIN’]该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。
- $_SERVER[‘SERVER_PORT’]Web 服务器使用的端口。默认值为 “80”。
- $_SERVER[‘SERVER_SIGNATURE’]返回服务器版本和虚拟主机名。
- $_SERVER[‘PATH_TRANSLATED’]当前脚本所在文件系统(非文档根目录)的基本路径。
- $_SERVER[‘SCRIPT_NAME’]返回当前脚本的路径。
- $_SERVER[‘SCRIPT_URI’]返回当前页面的 URI。
$_REQUEST
用于收集 HTML 表单提交的数据。
例:输入name,点提交,下方出现输入的name
1 | <html> <body> |
使用isset()函数判断表单是否提交
1 | if(isset($_post['submit']) |
$_POST
广泛用于收集提交 method=”post” 的 HTML 表单后的表单数据。
也常用于传递变量。
实例见上。
- $_GET 也可用于收集提交 HTML 表单 (method=”get”) 之后的表单数据。
- $_GET 也可以收集 URL 中的发送的数据。
1 | <html><body> |
常用数组函数
- 取数组长度:
count(array)
- 增加一个元素到结尾:
array_push(array, val)
- 是否存在某个元素:
in_array(val, array)
PHP 高级教程
PHP 多维数组
两维数组
1 | $cars = array ( |
这是一个 4 行 3 列 的数组 $cars[3][2]
用法:$cars[1][2] = 13
1 | echo $cars[0][0].": 库存:".$cars[0][1].", 销量:".$cars[0][2].".<br>"; |
打印两维数组表格:
1 | <?php |
PHP 日期
date() 函数
用于对日期或时间进行格式化
1 | date(format,timestamp) |
format 必需,规定时间戳的格式,见下面。
timestamp可选,规定时间戳,默认当前时间日期。
时间戳是一种字符序列,它表示具体事件发生的日期和事件。
- d - 表示月里的某天(01-31)
- m - 表示月(01-12)
- Y - 表示年(四位数)
- 1 - 表示周里的某天
- h - 带有首位零的 12 小时小时格式
- i - 带有首位零的分钟
- s - 带有首位零的秒(00 -59)
- a - 小写的午前和午后(am 或 pm)
1 | echo "今天是 " . date("Y-m-d") . "<br>"; |
自动版权年份
1 | © 2010-<?php echo date("Y")?> |
请注意:date() 会返回服务器的当前日期/时间!
获得时区
默认是服务器所在地点
1 | date_default_timezone_set("Asia/Shanghai"); |
mktime() 函数
返回日期的 Unix 时间戳。Unix 时间戳包含 Unix 纪元(1970 年 1 月 1 日 00:00:00 GMT)与指定时间之间的【秒数】,不考虑闰秒
mktime(hour,minute,second,month,day,year)
1 |
|
strtotime() 函数
用于把人类可读的字符串转换为 Unix 时间。
1 | strtotime(time,now) |
time:转化格式
now:对比的时候(当前时间可省略)
1 |
|
PHP 在将字符串转换为日期这方面非常聪明,所以您能够使用各种值(strtotime() 并不完美):
1 | $d=strtotime("tomorrow"); |
输出七月四日之前的天数:
1 |
|
PHP Include
include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并【复制】到使用 include 语句的文件中。
include 和 require 是相同的,除了错误处理方面:
- require 会生成致命错误(E_COMPILE_ERROR)并停止脚本(必需文件)
- include 只生成警告(E_WARNING),并且脚本会继续(不必需文件)
用法:
1 | <?php include 'footer.php';?> |
可以直接使用引用文件的变量(尽量使用安全的require,否则文件及其变量可能不存在)
PHP 文件
读取文件
1 | echo readfile("a.txt"); |
fopen() 的第一个参数包含被打开的文件名,第二个参数规定打开文件的模式。
如果 fopen() 函数未能打开指定的文件,下面的例子会生成一段消息:
1 |
|
文件会以如下模式之一打开:
- r 只读。文件指针在文件的开头开始。
- w 只写。删除文件的内容或创建一个新的文件,如果它不存在。文件指针在文件的开头开始。
- a只写。文件中的现有数据会被保留。文件指针在文件结尾开始。创建新的文件,如果文件不存在。
- x创建新文件为只写。返回 FALSE 和错误,如果文件已存在。
- r+读/写、文件指针在文件开头开始。
- w+ 读/写。删除文件内容或创建新文件,如果它不存在。文件指针在文件开头开始。
- a+读/写。文件中已有的数据会被保留。文件指针在文件结尾开始。创建新文件,如果它不存在。
- x+读/写。返回 FALSE 和错误,如果文件已存在。
fread() 的第一个参数包含待读取文件的文件名,第二个参数规定待读取的最大字节数。
读取单行文件 - fgets()
1 | echo fgets($myfile); |
调用 fgets() 函数之后,文件指针会移动到下一行。
检查 End-Of-File - feof()
1 |
|
读取单字符 - fgetc()
用法同fgets()
写入文件 - fwrite()
fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串。
1 | $myfile = fopen("new.txt", "w") or die("Unable!"); |
写出的文件是这样的:
1 | Bill Gates |
PHP 文件上传
文件上传 网页端
1 | <html><body> |
<form> 标签的 enctype 属性规定了在提交表单时要使用哪种内容类型。在表单需要二进制数据时,比如文件内容,请使用 “multipart/form-data”。
<input> 标签的 type=”file” 属性规定了应该把输入作为文件来处理。
上传脚本 服务端
1 | <?php |
使用 PHP 的全局数组 $_FILES,第二个下标可以是 “name“, “type“, “size“, “tmp_name“ 或 “error“。
在服务器的 PHP 临时文件夹创建了一个被上传文件的临时副本,会在脚本结束时消失。
拷贝到另外的位置:
1 | if (file_exists("upload/" . $_FILES["file"]["name"])) |
PHP Cookies
setcookie() 函数
用于设置 cookie。
注释:setcookie() 函数必须位于 标签之前。
setcookie(name, value, expire, path, domain);
一小时后过期:
1 | setcookie("user", "Alex Porter", time()+3600); |
cookie会自动URL编码、解码。
为防止 URL 编码,使用 setrawcookie()
$_COOKIE 变量
用于取回 cookie 的值。
1 | echo $_COOKIE["user"]; |
1 | // A way to view all cookies |
isset() 函数
确认是否已设置了 cookie
1 |
|
删除 cookie
使过期日期变更为过去的时间点。
1 | setcookie("user", "", time()-3600); |
PHP Sessions
session_start()
在您把用户信息存储到 PHP session 中之前,首先必须启动会话。
注释:session_start() 必须位于 标签之前:
1 | <?php session_start(); ?> |
上面的代码会向服务器注册用户的会话,以便您可以开始保存用户信息,同时会为用户会话分配一个 UID。
$_SESSION 变量
存储和取回 session 变量
1 | session_start(); |
isset() 函数
检测是否已设置 session 变量。
1 | if(isset($_SESSION['views'])) |
unset() 函数
用于释放指定的 session 变量:
1 |
|
session_destroy() 函数
彻底终结 session (清空):
1 |
|
PHP E-mail
mail() 发送邮件
1 | mail(to,subject,message,headers,parameters) |
接收者、主题、消息、[附加的标题]、[参数]
防止 email 注入(使用 PHP 过滤器)
1 | function spamcheck($field) |
PHP Error
die() 函数:基本的错误处理
1 | die("Error<br>"); |
1 | die(); |
set_error_handler():修改错误处理程序:
1 | set_error_handler("customError"); |
1 | set_error_handler("customError",E_USER_WARNING); // 加上错误级别 |
1 |
|
如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 “Uncaught Exception” (未捕获异常)的错误消息。
Try - 使用异常的函数应该位于 “try” 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
Throw - 这里规定如何触发异常。每一个 “throw” 必须对应至少一个 “catch”
Catch - “catch” 代码块会捕获异常,并创建一个包含异常信息的对象
创建一个自定义的 Exception 类
可以使用 exception 类的方法,比如 getLine() 、 getFile() 以及 getMessage()。
1 |
|
设置顶层异常处理器 (Top Level Exception Handler)
set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。
1 |
|
PHP Exception 过滤器
函数和过滤器
- filter_var() - 通过一个指定的过滤器来过滤单一的变量
- filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
- filter_input - 获取一个输入变量,并对它进行过滤
- filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
验证整数
1 | filter_var($int, FILTER_VALIDATE_INT) |
Validating 过滤器
用于验证用户输入
严格的格式规则(比如 URL 或 E-Mail 验证)
如果成功则返回预期的类型,如果失败则返回 FALSE
Sanitizing 过滤器
用于允许或禁止字符串中指定的字符
无数据格式规则
始终返回字符串
选项和标志用于向指定的过滤器添加额外的过滤选项。
不同的过滤器有不同的选项和标志。
1 |
|
验证表单
1 | if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)) |
通过 “GET” 方法传送的输入变量,
1、检测是否存在 “GET” 类型的 “email” 输入变量
2、如果存在,检测它是否是有效的邮件地址
净化输入
1 | if(!filter_has_var(INPUT_POST, "url")) |
通过 “POST” 方法传送的输入变量 (url),
1、检测是否存在 “POST” 类型的 “url” 输入变量
2、如果存在此输入变量,对其进行净化(删除非法字符),并将其存储在 $url 变量中
输入变量:”http://www.W3非o法ol.com.c字符n/“,则净化后的 $url 变量:
http://www.W3School.com.cn/
过滤多个输入
1 |
|
自定义数据过滤函数
1 |
|
PHP 表单
注意:在处理 PHP 表单时请关注安全!
表单是否存在
1 | if (isset($_REQUEST[$s])) { } |
GET 和 POST
者都创建数组(例如,array( key => value, key2 => value2, …))。此数组包含键/值对,其中的键是表单控件的名称,而值是来自用户的输入数据。
1 | <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> |
作用:$_SERVER[“PHP_SELF”] 返回当前执行脚本的文件名,将表单数据发送到页面本身
htmlspecialchars() 函数
把特殊字符转换为 HTML 实体。
这意味着 < 和 > 之类的 HTML 字符会被替换为 < 和 > 。这样可防止攻击者通过在表单中注入 HTML 或 JavaScript 代码(跨站点脚本攻击)对代码进行利用。
$_SERVER[“PHP_SELF”] 变量能够被黑客利用!
假设我们的一张名为 “test_form.php” 的页面中有如下表单:
1 | <form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>"> |
URL:”http://www.example.com/test_form.php"
上面的代码会转换为:
1 | <form method="post" action="test_form.php"> |
如果输入URL:
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
在这种情况下,上面的代码会转换为:
1 | <form method="post" action="test_form.php"/><script>alert('hacked')</script> |
这段代码加入了一段脚本和一个提示命令。并且当此页面加载后,就会执行 JavaScript 代码(用户会看到一个提示框)。
<script> 标签内能够添加任何 JavaScript 代码!
使用 htmlspecialchars() 函数能够避免 $_SERVER[“PHP_SELF”] 被利用。
表单代码是这样的:
1 | <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> |
htmlspecialchars() 函数把特殊字符转换为 HTML 实体。
现在,如果用户试图利用 PHP_SELF 变量,会导致如下输出:
1 | <form method="post" action="test_form.php/"><script>alert('hacked')</script>"> |
无法利用,没有危害!
htmlspecialchars() 函数可以使提交的代码字段不会被执行,因为会被保存为转义代码,当作普通的文本,就像这样:
1 | <script>location.href('http://www.hacked.com')</script> |
转义后的:
1 | <script>location.href('http://www.hacked.com')</script> |
现在这条代码显示在页面上或 e-mail 中是安全的。
检查函数
在用户提交该表单时,我们还要做两件事:
1.(通过 PHP trim() 函数)去除用户输入数据中不必要的字符(多余的空格、制表符、换行)
2.(通过 PHP stripslashes() 函数)删除用户输入数据中的反斜杠(\)
1 |
|
输入提示(必填项未输入/格式错误等)
1 | Name: <input type="text" name="name" value="<?php echo $name;?>"> |
格式验证(正则表达式)
名字是否包含空格
1 | $name = test_input($_POST["name"]); |
邮箱
1 | preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email) |
URL(允许斜杠 /,需转义)
1 | preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/% =~_|]/i",$website) |
PHP 数据库
连接数据库
1 | mysql_connect(servername,username,password); |
servername 默认是 “localhost:3306”
username 默认值是拥有服务器进程的用户的名称
password 默认为””
创建数据库
1 | CREATE DATABASE database_name |
选择数据库
1 | mysql_select_db("database_name", $con); |
建表、添加、选取等之前必须选择数据库
创建表
1 | CREATE TABLE table_name |
1 |
|
修改表名
1 | mysql_query("ALTER TABLE `$old_tablename` RENAME TO `$tablename`"); // 注意:是 ` ` 而不是 单引号 |
删除表
1 | mysql_query("DROP TABLE `$tablename`"); |
插入数据(不分大小写):INSERT INTO
1 | mysql_query("INSERT INTO Persons (FirstName, LastName, Age) VALUES ('Glenn', 'Quagmire', '33')"); |
注意values里面的单引号,必须要加上去。
表单数据到数据库
1 | $sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')"; |
选取数据:SELECT
1 | $result = mysql_query("SELECT * FROM Persons"); |
按行读取选取的数据
1 | mysql_fetch_array(data,array_type); |
mysql_fetch_array() 是 mysql_fetch_row() 的扩展,不会慢很多。
array_type 规定返回哪种结果。可能的值:
- MYSQL_ASSOC - 关联数组
- MYSQL_NUM - 数字数组
- MYSQL_BOTH - 默认。同时产生关联和数字数组
1 | while($row = mysql_fetch_array($result)) |
匹配指定条件:WHERE
运算符: = != < > <= >=
- BETWEEN 介于一个包含范围内
- LIKE 搜索匹配的模式
1 | $result = mysql_query("SELECT * FROM Persons WHERE FirstName='Peter'"); |
###排序
- 排序:ORDER BY
SELECT * FROM Persons ORDER BY age - 默认升序,DESC 关键词降序。
ORDER BY column_name DESC - 多列排序时,只有第一列相同时才使用第二列:
ORDER BY column_name1, column_name2
修改数据:UPDATE
1 | mysql_query("UPDATE Persons SET Age = '36' WHERE FirstName = 'Peter' AND LastName = 'Griffin'"); |
删除数据:DELETE FROM
1 | mysql_query("DELETE FROM Persons WHERE LastName='Griffin'"); |
ODBC
不多说,直接看下面的实例吧!
1 | <html> |
AJAX
创建 XMLHttpRequest 对象
1 | function GetXmlHttpObject() |
实时搜索
前端 HTML
1 | <html> |
后端 JavaScript
1 | var xmlHttp |
其他
取网页源码
1 | $ret = file_get_contents("http://acm.hdu.edu.cn/showproblem.php?pid=1000"); // 取网页源码 |
网址重定向
1 | header("Location:" . $_SERVER['PHP_SELF']); // 默认页面 |
获取 IP
1 | function getIP() // 获取真实的IP |
获取时间文本
时间戳:time()
1 | function gettime() // 获取当前时间文本 |
自制数据库模板
1 | define("MySQL_servername", "localhost"); |
自制表单操作模板
1 | function seize() // 函数重载吧…… |
END
恭喜您,看完了整篇文章!