php自学笔记
这篇笔记是今年暑假自学时随手记录的,排版什么的都比较乱,也不太体系化,先发上来,以后整理。
1、定义:
超文本与处理器,服务器端脚本
2、功能:
动态生成网页内容
创建打开读取写入关闭服务器上的文件
收集表单数据
发送和接收cookies
增删改数据库
限制用户访问某些页面
加密数据
3、样式:
<?php ?>包含php脚本,分号结束语句,注释方法与C一样
4、变量:
以$开头命名方式与C一样,区分大小写
变量不用声明,赋值时即创建
弱类型语言
作用域
local 定义在函数内部
global 定义在函数外部 存储在GLOBALS[index]数组中,index是变量名
static 使得一个变量在函数完成后不被删除的局部变量
parameter
5、echo & print
echo 输出一个或多个字符串
print 只输出一个字符串,返回值永远是1
速度上来说echo更快
echo和echo()等价
printhe print()等价
6、变量类型
var_dump()函数返回变量的数据类型和值
字符串 ""或''
整型 0x代表16进制 0代表8进制
浮点型
布尔型 true false
数组 $people = array('male','female');
对象 可以用于存储数据,对象必须声明 使用class关键字声明类对象 类是可以包含属性和方法的结构
class Car
{
var $color;
function Car($color="green") {
$this->color = $color;
}
function what_color() {
return $this->color;
}
}
空 NULL 用于清空变量数据
7、常量
常量不需要用$符号修饰
define(string $name,mixed $value[,bool $case_insensitive = false])函数用于设置常量
变量名 值 是否大小写敏感 ture表示不敏感
eg: define("para","变量的值",true)
则 para和Para都表示这个变量
常量默认是全局变量
8、字符串
赋值时加引号
并置运算符 . 用于把两个字符串值连接起来
eg:$t1." ".$t2
strlen()求字符串值的长度(字符数)
strpos()在字符串中查找一个字符或一段指定的文本(模式匹配),返回第一个匹配字符的位置或false,下标从0开始
http://www.runoob.com/php/php-ref-string.html
9、运算符
算术运算符
加减乘除取模与C语言一致,取反-x,并置a.b
赋值运算符
支持+=,-=与C语言一致
递增递减运算符
++x,x++的规则与C语言一致
比较运算符
基本与C一致,恒等于 === 代表值和类型都相同,!==表示不恒等于,!=和<>都表示不等于
逻辑运算符
与 and &&
或 or ||
非 !
数组运算符
+ 集合
== 相等 键值对相同
=== 恒等 键值对相同 顺序相同 类型相同
三元运算符
与C语言一致
若省略第二个表达式则表达式一成立则返回表达式一否则返回表达式三
expe1?:expe3
expe1?expe2:expe3
10、数组
用array()创建
用count()获取数组长度
关联数组(参考C的hashmap)
eg:$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
foreach($age as $x=>$x_value)
{
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
http://www.runoob.com/php/php-ref-array.html
数组排序
sort() - 对数组进行升序排列
rsort() - 对数组进行降序排列
asort() - 根据关联数组的值,对数组进行升序排列
ksort() - 根据关联数组的键,对数组进行升序排列
arsort() - 根据关联数组的值,对数组进行降序排列
krsort() - 根据关联数组的键,对数组进行降序排列
多维数组
eg:array(array(1,1,1),array(2,2,2),array(3,3,3))
11、超级全局变量
$GLOBALS 包含了全部变量的全局组合数组
$_SERVER 包含服务器相关的配置信息
$_REQUEST 收集HTML表单提交的数据
$_POST 收集method="post"的表单数据
$_GET 收集method="get"的表单数据
$_FILES
$_ENV
$_COOKIE
$_SESSION
http://www.runoob.com/php/php-superglobals.html
12、魔术变量
许多运行起来之后才会出现的变量,其值会随着位置的改变而不同
__LINE__ 文件中的当前行号
__FILE__ 文件的完整路径和文件名
__DIR__ 文件所在的路径
__FUNCTION__返回该函数被定义时的名字
__CLASS__ 返回该类被定义时的名字
__TRAIT__ 代码复用的一个方法叫traits
__METHOD__ 返回该方法被定义时的名字
__NAMESPASE__ 返回当前的命名空间
13、条件和循环
条件
和C一致,也有switch
循环
while - 只要指定的条件成立,则循环执行代码块
do...while - 首先执行一次代码块,然后在指定的条件成立时重复这个循环
for - 循环执行代码块指定的次数
foreach - 根据数组中每个元素来循环代码块
14、函数
function name($para1,$para2)
{
return $para1 + $para2
}
15、命名空间
解决两大问题:
用户的代码和类库的代码名字冲突
提高代码可读性
用namespace声明
只有定义源文件编码方式的declare语句可以放在namespace之前
16、面向对象
类 - 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
对象 - 是类的实例。
成员变量 - 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
成员函数 - 定义在类的内部,可用于访问对象的数据。
继承 - 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
父类 - 一个类被其他类继承,可将该类称为父类,或基类,或超类。
子类 - 一个类继承其他类称为子类,也可称为派生类。
多态 - 多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。
不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
重载 - 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
抽象性 - 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。
一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。
任何类的划分都是主观的,但必须与具体的应用有关。
封装 - 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
构造函数 - 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
析构函数 - 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
$this 表示对象自身
new 用于实例化类对象
-> 用于调用成员方法、成员变量
extends 继承
interface 定义一个接口,用于指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容
implements 实现一个接口
abstract 定义一个抽象类,包含抽象方法的类都是抽象类,抽象方法只声明调用方法,不定义具体实现,
继承之后,子类必须包含父抽象类的全部方法且访问控制只能相同或更宽松
static 声明属性或方法为静态,可以不实例化直接访问
静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
静态属性不可以由对象通过 -> 操作符来访问。
final 父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
:: 调用父类的方法
成员访问控制
public(公有):公有的类成员可以在任何地方被访问。
protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
private(私有):私有的类成员则只能被其定义所在的类访问。
17、表单处理
用于处理html的form提交的数据
验证表单&安全性措施
正则匹配用户输入的内容是否合法
利用trim()去除不必要的空格换行tab;
利用stripslashes()去除反斜杠
利用htmlspecialchars()将html预定义的字符转换为html实体(使得恶意嵌入的代码失效)
正则匹配
int preg_match ( string $pattern , string $subject [, array $matches [, int $flags ]] )
在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。
如果提供了 matches ,则其会被搜索的结果所填充。
$matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。
eg: preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)
$_GET
用于收集来自method="get"的表单中的值
从带有 GET 方法的表单发送的信息,对任何人都是可见的(会显示在浏览器的地址栏),并且对发送信息的量也有限制。
所以在发送密码或其他敏感信息时,不应该使用这个方法!
然而,正因为变量显示在 URL 中,因此可以在收藏夹中收藏该页面。在某些情况下,这是很有用的。
HTTP GET 方法不适合大型的变量值。它的值是不能超过 2000 个字符的。
eg:<?php echo $_GET["fname"]; ?>
<?php echo $_GET["age"]; ?>
$_POST
用于收集来自method="post"的表单中的值
从带有 POST 方法的表单发送的信息,对任何人都是不可见的(不会显示在浏览器的地址栏),并且对发送信息的量也没有限制。
然而,默认情况下,POST 方法的发送信息的量最大值为 8 MB(可通过设置 php.ini 文件中的 post_max_size 进行更改)。
eg:<?php echo $_POST["fname"]; ?>
<?php echo $_POST["age"]; ?>
$_REQUEST
包含了 $_GET、$_POST 和 $_COOKIE 的内容。
可用来收集通过 GET 和 POST 方法发送的表单数据。
eg:<?php echo $_REQUEST["fname"]; ?>
<?php echo $_REQUEST["age"]; ?>
18、日期
date()将时间戳转化为可读性好的日期
eg:
<?php
echo date("Y/m/d") . "<br>";
echo date("Y.m.d") . "<br>";
echo date("Y-m-d");
?>
http://www.runoob.com/php/php-date.html
19、include & require
在服务器执行php之前在该文件中插入一个文件的内容
include如果出错,会继续执行下去
require如果出错,会终止后续的执行
eg:
<?php include 'header.php'; ?>
20、文件
fopen() 用于打开文件
fclose()用于关闭文件
feof() 检测文件是否到达末尾
fgets() 逐行读取文件
fgetc() 逐字符读取文件
http://www.runoob.com/php/php-file.html
21、文件上传
文件上传表单+处理php代码
表单:
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
enctype表示提交表单时使用的内容类型
type="file"规定将输入作为文件处理
文件上传是一个安全风险,要谨慎开放
使用$_FILES作为文件上传的容器
通过对$_FILES的各个属性做限制来约束上传文件的属性
$_FILES["file"]["name"] - 上传文件的名称
$_FILES["file"]["type"] - 上传文件的类型
$_FILES["file"]["size"] - 上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码
上传之后还需要保存的操作,将其拷贝到upload文件夹下,否则只有一个临时的文件副本。
eg:
if (file_exists("upload/" . $_FILES["file"]["name"])){
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
} else {
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
22、Cookie
常用于识别用户
是一种服务器留在用户计算机上的小文件,当同一台计算机通过浏览器请求页面时,这台计算机将会发送cookie
setcookie() 设置cookie值 必须位于<html>标签之前
setcookie(name, value, expire, path, domain); //cookie名,值,过期时间(单位是秒),路径,主机名
setrowcookie() 设置原始cookie,不会被URL编码
$_COOKIE['cookie名'] 取回cookie值
eg:
<?php
if (isset($_COOKIE["user"]))
echo "欢迎 " . $_COOKIE["user"] . "!<br>";
else
echo "普通访客!<br>";
?>
将expire的时间设置为过去,值设置为空即可删除该cookie
eg:
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>
23、Session
用于存储关于用户会话的信息,或者更改用户会话的设置。
Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的。
Session 的工作机制:
为每个访客创建一个唯一的 id (UID),并于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。
启动会话
session_start()
必须位于<html>标签之前
向服务器注册会话以便保存用户信息并分配一个UID
存储和引用Session
$_SESSION['session名']
销毁Session
unset($_SESSION['session名']) 释放指定的session变量
session_destroy() 彻底销毁session 将会重置session会失去所有为未储的session
24、E-mail
mail(to,subject,message,headers,parameters)
*需要有一个已安装且正在运行的邮件系统,通过php.ini设置
为了防止注入攻击需要对输入做检查和过滤
filter_var()
25、错误处理
报错时会直接将错误发送给浏览器包含文件名,行号,错误的消息,但这显然是不安全的
解决办法:
A. die(),用if...else...添加判断,如果出错,用die()返回提示消息,但是这种办法会终止脚本的执行
eg:
<?php
if(!file_exists("welcome.txt"))
{
die("文件不存在");
}
else
{
$file=fopen("welcome.txt","r");
}
?>
B. 创建自定义错误处理器
error_function(error_level,error_message,error_file,error_line,error_context)
http://www.runoob.com/php/php-error.html
eg:
function customError($errno, $errstr)// 错误处理函数
{
echo "<b>Error:</b> [$errno] $errstr<br>";
echo "脚本结束";
die();
}
set_error_handler("customError");// 设置错误处理函数
26、异常
try throw catch结构来实现,总体和Java是类似的
可以抛出多个异常被多个catch捕获并处理
可以重新抛出异常,对用户显示友好的提示,对后台显示真正的错误位置(在catch块中再次throw)
顶层异常处理器,用于处理所有未被捕获的异常,set_exception_handler()
27、过滤器
过滤的目的是防止非安全来源的数据对系统造成破坏
表单数据,cookies,web服务数据,服务器变量,数据库查询结果都是外部数据都需要过滤
filter_var() - 通过一个指定的过滤器来过滤单一的变量
filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
filter_input - 获取一个输入变量,并对它进行过滤
filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
参数包含待过滤的变量和过滤器(例如,FILTER_VALIDATE_EMAIL用于验证传入的变量是否是一个email地址)
过滤器种类和过滤函数参考链接http://www.runoob.com/php/php-ref-filter.html
过滤器有两类Validating和Sanitizing
V用于验证用户输入,有严格的格式规则(URL,E-mail),如果成功则返回预期的类型否则返回false
S用于允许或禁止字符串中指定的字符,无数据格式规则,始终返回字符串
通过filter callback可以调用自己设置的过滤器,参数有一个关联数组,键为options
<?php
function convertSpace($string)
{
return str_replace("_", ".", $string);
}
$string = "www_runoob_com!";
echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertSpace"));
?>
http://www.runoob.com/php/php-filter.html
28、PHP与mySQL
A. 连接和关闭数据库
有mysqli和PDO两种办法,mysqli专用,PDO通用
mysqli:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
// 创建连接
$conn = new mysqli($servername, $username, $password);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
//关闭连接
$conn->close();
?>
PDO:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
//需要指定数据库名
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
echo "连接成功";
}
catch(PDOException $e)
{
echo $e->getMessage();
}
//关闭连接
$conn = null;
?>
B. 创建数据库
mysqli:
$sql = "CREATE DATABASE myDB";
if ($conn->query($sql) === TRUE) {
echo "数据库创建成功";
} else {
echo "Error creating database: " . $conn->error;
}
PDO:
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// 设置 PDO 错误模式为异常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE DATABASE myDBPDO";
// 使用 exec() ,因为没有结果返回,如果出错会抛出异常进入catch块
$conn->exec($sql);
echo "数据库创建成功<br>";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
C. 创建表
和标准sql一样的办法,执行过程与B类似,mysqli判断返回值真假,PDO直接exec()
D. 插入、修改、删除数据
和标准sql一样的办法,执行过程与B类似,mysqli判断返回值真假,PDO直接exec()
E. 查询数据
mysqli:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);//返回查询结果集
if ($result->num_rows > 0) {
// 输出每行数据
while($row = $result->fetch_assoc()) {//fetch_assoc用于取出每一个结果
echo "<br> id: ". $row["id"]. " - Name: ". $row["firstname"]. " " . $row["lastname"];
}
} else {
echo "0 个结果";
}
$conn->close();
?>
PDO:
<?php
echo "<table style='border: solid 1px black;'>";
echo "<tr><th>Id</th><th>Firstname</th><th>Lastname</th><th>Email</th><th>Reg date</th></tr>";//设置表头
class TableRows extends RecursiveIteratorIterator { //构造出一个表的结构
function __construct($it) {
parent::__construct($it, self::LEAVES_ONLY);
}
function current() {
return "<td style='width: 150px; border: 1px solid black;'>" . parent::current(). "</td>";
}
function beginChildren() {
echo "<tr>";
}
function endChildren() {
echo "</tr>" . "\n";
}
}
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT * FROM MyGuests");
$stmt->execute();
// 设置结果集为关联数组
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) {
echo $v;
}
$dsn = null;
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
echo "</table>";
?>
F. 预处理语句
目的:
在大量重复操作时,提高数据库操作效率,节省带宽
防止SQL注入攻击,
mysqli:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 预处理及绑定
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);//sss表示后续共三个参数,每个参数都是string类型 i(int) d(double) s(string) b(BLOB二进制大对象)
// 设置参数并执行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
echo "新记录插入成功";
$stmt->close();
$conn->close();
?>
PDO:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 设置 PDO 错误模式为异常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 预处理 SQL 并绑定参数,这里与mysqli略有不同
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
// 插入行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();
// 插入其他行
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
// 插入其他行
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
echo "新记录插入成功";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>