人小时候总是鄙夷“酒肉朋友”这四个字,长大后才发现,在你最难过的时候,只有喝杯酒和大块吃肉能让你稍微舒服些。某种意义上说酒肉才是你永恒的好朋友,因为它们从不弃你而去,所以世界上伤心的胖子越来越多。
文件包含
文件包含有点类似Python中的包,你可以自己写包然后在另一个脚本中调用你自己写的包,PHP的文件包含有两个函数include与require,看看他们的区别:
- require 生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会停止执行。
- include 生成一个警告(E_WARNING),在错误发生后脚本会继续执行。
区别就是require出错了就停止了并且报错,include出错了还可以继续执行。
案例一:
在当前目录下有一个index.php,里面的内容是:
<?php
header("Content-type: text/html; charset=utf-8");
echo 'www.sxadmin.github.io';
echo "<br>";
echo '不将就';
?>
同目录下新建一个PHP文件:
<?php
header("Content-type: text/html; charset=utf-8");
include 'index.php';
?>
运行结果:
www.sxadmin.github.io
不将就
如果使用require的话就直接把include改掉就ok。
案例二
上面只是一个简单的包含调用,如果你包含调用的文件中有变量需要你使用的话,看看下面的例子。
首先写一个菜单超链接文件,并且包含两个变量$name与$age,内容如下:
<?php
header("Content-type: text/html; charset=utf-8");
echo '<a href="/">首页</a>
<a href="/phpinfo.php">info信息</a>
<a href="/l.php">探针</a>';
$name='langzi';
$age='22';
?>
运行结果:
点击探针的话或跳转过去的哟~
这个时候我可以调用后直接使用被调用的文件内的变量哦~
<html>
<body>
<div class="leftmenu">
<?php
header("Content-type: text/html; charset=utf-8");
include 'index.php';
echo '<hr>';
echo $name.'<br>';
echo $age;
?>
</body>
</html>
运行结果:
文件处理
就像Python中打开处理文本一样,除了格式上略有不同。
<?php
header("Content-type: text/html; charset=utf-8");
// 设置编码
$file = fopen("index.txt", "r") or exit("无法打开文件!");
// 打开文件,如果不存在输输出无法打开文件
while(!feof($file))
{
echo fgets($file). "<br>";
}
// 读取文件每一行,直到文件结尾
fclose($file);
// 关闭文件
?>
相关函数:
feof() 函数检测是否已到达文件末尾(EOF)。
if (feof($file)) echo “文件结尾”;
fgets() 函数用于从文件中逐行读取文件。在调用该函数之后,文件指针会移动到下一行。
fgetc() 函数用于从文件中逐字符地读取文件。在调用该函数之后,文件指针会移动到下一个字符。
关于PHP中文件操作还有很多知识点,这里不一一列举,详细请参考PHP文件操作
Cookie
使用setcookie()创建cookies,注意setcookie() 函数必须位于 标签之前。下面的例子是先创建一个cookie值,有效时间为一个小时
<?php
setcookie("langzi", "zhaohan", time()+3600);
?>
<html>
<?php
// 输出 cookie 值
echo $_COOKIE["langzi"];
echo '<hr>';
// 查看所有 cookie
print_r($_COOKIE);
?>
</html>
运行结果:
zhaohan
--------------------------------------------------
Array ( [langzi] => zhaohan [Pycharm-31941b8e] => 016cf837-253e-4bd4-bebc-bb57ec4bdc6e [Phpstorm-d94e29df] => 9ab3f44d-78b3-48ff-9a0d-621a484e0cdf )
删除COOKIE
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("langzi", "", time()-3600);
?>
错误/异常/捕获异常处理
PHP中对错误异常的处理比Python中要多一些,错误处理PHP中可以使用die()函数来处理,但是重点还是放在异常处理与异常捕获上面。
- Try - 和Python中一样。
- Throw - 里规定如何触发异常。有点像Python异常处理里面的raise抛出异常,但是在PHP当中你先定义出现异常的条件,每一个 “throw” 必须对应至少一个 “catch”。如果抛出了异常,就必须捕获它。
- Catch - 和Python中的Exception一样,”catch” 代码块会捕获异常,并创建一个包含异常信息的对象。
案例:
<?php
header("Content-type: text/html; charset=utf-8");
// 创建一个有异常处理的函数
function checkNum($number)
{
if($number>1)
{
throw new Exception("变量值必须小于等于 1");
// 出现异常的条件,新建一个异常对象
}
return true;
}
// 在 try 块 触发异常
try
{
checkNum(2);
// 如果抛出异常,以下文本不会输出
echo 'okok';
//如果是正常的话就执行上面的输出okok,但是传入参数2大于1,会出现异常
}
// 捕获异常
catch(Exception $e)
// 这里就像Python的 except Exception as e
{
echo 'Message: ' .$e->getMessage();
}
?>
运行结果:
Message: 变量值必须小于等于 1
创建一个异常的类
就像Python的类class一样,PHP中创建自定义的异常处理程序非常简单。我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。
这个自定义的 customException 类继承了 PHP 的 exception 类的所有属性,可向其添加自定义的函数。:
<?php
header("Content-type: text/html; charset=utf-8");
class customException extends Exception
// 从Exception继承过来,类似Py的class(exception)它从旧类继承了属性和方法,我们可以使用 exception 类的方法,比如 getLine()、getFile() 和 getMessage()。
{
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);
}
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>
运行结果:
错误行号 22 in E:\PHPSTUDY\PHPTutorial\WWW\PHP study5-10\PHP-base\php-exeption.php: someone@example...com 不是一个合法的 E-Mail 地址
在类中public是用来声明公共作用域中的属性。公共属性,就是可以有相应的对象直接操作和访问的。
操作MYSQL数据库
就像在Python中操作数据库一样,在PHP中使用mysql_xx()函数可以直接对MYSQL数据库进行连接关闭与增删改查。
连接数据库与关闭
<?php
mysql_connect("localhost:3306",'root','root');
mysql_close();
?>
和Python中的oymysql一样,首先定义一个数据库连接,最后关闭连接。定义一个变量$coon当作这个数据库的连接变量。如果连接失败就报个异常。
<?php
$coon = mysql_connect('localhost:3306','roottt','root');
if (!$coon) {
echo 'Could not connect: ' . mysql_error();
}
?>
运行结果:
Warning: mysql_connect(): Access denied for user 'roottt'@'localhost' (using password: YES) in E:\PHPSTUDY\PHPTutorial\WWW\PHP study5-10\PHP-base\php_mysql.php on line 2
Could not connect: Access denied for user 'roottt'@'localhost' (using password: YES)
创建数据库与表
<?php
/**
* Created by PhpStorm.
* User: Sxadmin
* Blog: sxadmin.github.io
* Date: 2018/5/18 0018
* Time: 15:08
*/
header("Content-type: text/html; charset=utf-8");
$coon = mysql_connect('127.0.0.1','root','root');
if (!$coon){
echo '连接数据库失败'.mysql_error();
}
//创建一个数据库 lang
if (mysql_query('create database lang',$coon)){
echo '数据库创建成功';
}else{
echo '数据库创建失败'.mysql_error();
}
// 在lang数据库创建一个表 msg
// 首先选择数据库,使用mysql_select_db
mysql_select_db('lang');
// 然后开始创建表了
// 就像在Python中一样,你可以把SQL语句放在一个变量里面,注意这里的语法不一样,括号内容不要加引号
$sql = 'create table msg(
name varchar(10),
age varchar(10)
)';
// 执行这条SQL语句
if (mysql_query($sql,$coon)){
echo 'msg表创建成功';
}else{
echo 'msg表创建失败'.mysql_error();
}
mysql_close();
?>
运行结果:
数据库创建成功msg表创建成功
数据库中也多了lang这个数据库,其中有msg这个表,可以增加一个自增长的ID作为主键,此时SQL语句可以这么写。
$sql = "CREATE TABLE Persons
(
personID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(personID),
FirstName varchar(15),
LastName varchar(15),
Age int
)";
增加数据
和Python中一样,知道MYSQL的基础语法就好了,增删改查与pymysql一样,只是记住PHP的语法比如括号引号要注意即可。
<?php
/**
* Created by PhpStorm.
* User: Sxadmin
* Blog: sxadmin.github.io
* Date: 2018/5/18 0018
* Time: 15:32
*/
header("Content-type: text/html; charset=utf-8");
$coon = mysql_connect('localhost:3306','root','root');
if (!$coon){
echo '数据库连接失败'.mysql_error().'<br>';
}else{
echo '数据库连接成功'.'<br>';
}
mysql_select_db('lang');
$sql="insert into msg(name,age) values ('langzi','18')";
if (!mysql_query($sql,$coon)){
echo '数据插入失败<br>';
}else{
echo '数据插入成功<br>';
}
mysql_close($coon);
?>
运行结果:
数据库连接成功
数据插入成功
查看数据库,可以看到数据插进去了…
name|langzi
age |18
获取表单提交的内容
$sql="INSERT INTO Persons (Name, Age) VALUES ('$_POST[name]','$_POST[age]')";
查询数据
<?php
/**
* Created by PhpStorm.
* User: Sxadmin
* Blog: sxadmin.github.io
* Date: 2018/5/18 0018
* Time: 15:32
*/
header("Content-type: text/html; charset=utf-8");
$coon = mysql_connect('localhost:3306','root','root');
if (!$coon){
echo '数据库连接失败'.mysql_error().'<br>';
}else{
echo '数据库连接成功'.'<br>';
}
mysql_select_db('lang');
$sql="select * from msg";
$result = mysql_query($sql,$coon);
if (!$result){
echo '数据查询失败<br>'.mysql_error();
}else{
echo '数据查询成功<br>';
// 这里和pymysql一样,用一个变量存储获取到的数据
while($row = mysql_fetch_array($result))
// 打印这个变量
{
echo $row['name'] . " " . $row['age'];
echo "<br />";
}
}
mysql_close($coon);
?>
运行结果:
数据库连接成功
数据查询成功
langzi 18
要注意的是,这个迭代遍历的结果的值必须与数据库的字段名一致,比如$row[‘name’]就不能用$row[‘naaame’]。
后面的改与删除都和pymysql差不多,只要记住php的语法结构上的差别即可。
文件上传
这个是一个很大的类目,在后面的安全审计中占用很重要的地位,看看php怎么实现文件上传先参考PHP基础
测试上传文件有一个文件夹和两个文件
|-----upload # 文件上传的目录
|-----form.html # 表单文件
|-----upload_file.php # php 上传代码
让我们来逐一分析这些代码:
<html>
<head>
<meta charset="utf-8">
<title>langzi-test-upload</title>
</head>
<body>
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<!--提交到当目录下的upload_file.php文件-->
<!--application/x-www-form-urlencoded是只能上传文本格式的文件,multipart/form-data是将文件以二进制的形式上传,这样可以实现多种类型的文件上传 -->
<label for="file">文件名:</label>
<!--label 元素不会向用户呈现任何特殊的样式。不过,它为鼠标用户改善了可用性,因为如果用户点击 label 元素内的文本,则会切换到控件本身。-->
<input type="file" name="file" id="file"><br>
<!--选择文件框框-->
<input type="submit" name="submit" value="提交">
<!--上传文件按钮-->
</form>
</body>
</html>
运行结果:
继续分析上传的PHP代码:
<?php
header("Content-type: text/html; charset=utf-8");
$allowedExts = array("gif", "jpeg", "jpg", "png");
// 数组内保存是允许上传的文件后缀
$temp = explode(".", $_FILES["file"]["name"]);
//explode把字符串变成数组,这个就像Python的字典变成JSON一样,不过只是像并非性质一样。参考https://sxadmin.github.io/PHP之String函数笔记.html
//通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
echo $_FILES["file"]["size"];
// 输出文件名和大小
$extension = end($temp);
// 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800)
// 小于 200 kb
&& in_array($extension, $allowedExts))
// in_array() 函数搜索数组中是否存在指定的值。
// php中的关系运算符:&&(and)、||(or)、xor(亦或)、!(非)
{
if ($_FILES["file"]["error"] > 0)
// 上传文件的返回信息中如果出现error这个单词就说明上传失败,有点类似Py中的find('error')>0
{
echo "错误:: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";
// 判断当期目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
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"];
}
}
}
else
{
echo "非法的文件格式";
}
?>
选择文件再上传