渗透测试-04:PHP

PHP 学习

语言规则

  • HTMLbody 标签里的 <?php ?> 标签里写语句

  • 语句末尾要加 ;

  • 注释:// 单行注释 # 单行注释 /*多行注释*/

  • 换行符可用 PHP_EOL 替代

  • 不区分大小写:关键词、类名、函数名

  • 区分大小写:变量名

  • 0null 值相等,类型不相等

  • 变量定义:$变量名

  • 变量作用域:

    local:函数内部声明的变量,仅能在函数内部访问

    global $变量名:函数内部调用外部全局变量,也可以使用 $GLOBALS[变量名] 访问全局变量

    static $变量名:函数执行结束后变量的值不被删除

  • 常量定义:define("__大写常量名__", 常量值)

  • $x <=> $yx<y返回-1,x=y返回0,x>y返回+1

  • 打印输出:echo 输出的速度比 print 快,可以使用括号,也可以不用括号

    echo $变量名:可以输出一个或多个字符串,没有返回值

    print $变量名:只允许输出一个字符串,返回值总为 1

    print_r():可以结构化打印数组变量,可以设置返回值

    var_dump():打印数据类型和值,可以结构化打印数组变量

  • . 拼接字符串

  • 引号的区别:

    单引号:不解析字符串里的 $变量名

    双引号:解析字符串里的 $变量名

  • 数组:可以用 array()[] 两种方法定义

    索引数组["orange", "apple", "banana"]

    关联数组["a"=>"星期一", "b"=>"星期二", "c"=>"星期三"]

数据类型

标准类型 - String、Integer、Float、Boolean
复合类型 - Array、Object
特殊类型 - Resource、NULL

自动类型转换:2+"2abc"=4

严格类型要求:<?php declare(strict_types=1); ?>

函数返回类型声明:(严格类型条件下)

<?php declare(strict_types=1); // strict requirement
function addNumbers(float $a, float $b) : float {
  return $a + $b;
}
echo addNumbers(1.2, 5.2); // 报错
?>

变量引用

<?php
function add_five(&$value) {
  $value += 5;
}

$num = 2;
add_five($num);
echo $num; // 7
?>

字符串函数

字符串长度 - strlen()
字符串反转 - strrev()
字符串截取 - substr()
字符串替换 - str_replace('要替换的字符串','新字符串','原字符串')
字符串的单词数 - str_word_count()
在原字符串中寻找新字符串并返回新字符串的索引 - strpos('原字符串','新字符串')
删除左边空格 - ltrim()
删除右边空格 - rtrim()
删除两边空格 - trim()
转小写 - strtolower()
转大写 - strtoupper()
删除 html 标签 - strip_tags()
转义 html 标签 - htmlspecialchars()
去除数据中的反斜杠(\) - stripslashes()

数组迭代器

foreach($names as $name){echo $name, "<br>";}
foreach($arr as $key=>$value){echo $key, $value;}

数组函数

数组元素个数 - count($数组变量名)
数组添加元素 - array_push($数组变量名, 值)
获取所有键名 - array_keys($数组名)
获取所有值 - array_values($数组名)
判断值是否存在于数组 - in_array(值, $数组名, true) // 第三个参数为是否开启严格模式(可选)

常用函数

升序排序 - sort()
降序排序 - rsort()
根据值升序排序 - asort()
根据键升序排序 - ksort()
根据值降序排序 - arsort()
根据键降序排序 - krsort()
查看类型 - gettype()
序列化 - serialize()
反序列化 - unserialize()
URL编码 - urlencode()
URL解码 - urldecode()
判断变量是否已被设置 - isset()
释放给定的变量 - unset()
判断变量是否为空 - empty()
字符串转数组 - expload()
数组转字符串 - impload()
输出一条消息,并停止往下执行 - exit() 或 die()
时间戳转格式化时间 - date('Y-m-d H:i:s', time())
设置中国时区 - date_default_timezone_set('PRC')
函数检查某常量是否存在 - defined()
输出当前文件的绝对路径 - __DIR__
函数解析URL,返回其组成部分 - parse_url()
函数用于检测变量是否是字符串 - is_string()
字符串 md5 加密 - md5()
单向字符串散列加密 - crypt('字符串', '盐值')
可防止时序攻击的字符串比较 - hash_equals(string $known_string, string $user_string)
获取文件名后缀 - pathinfo('文件名')['extension']

require 和 include

// 通常放在 PHP 脚本程序的最前面,在一开始就加载
// 出错时产生 E_ERROR 级别的错误,导致脚本中止
// 如果可能执行多次的代码,则使用 require() 效率比较高
require("文件.php")
// 检查该文件是否已经被包含过,如果是则不会再次包含
require_once("文件.php")
    
// 一般是放在流程控制的处理区段中,在用到时加载
// 出错时产生警告 E_WARNING,脚本会继续运行
// 如果每次执行代码时是读取不同的文件,或者有通过一组文件迭代的循环,就使用 include() 语句
include("文件.php")
// 唯一区别是如果该文件中已经被包含过,则不会再次包含,且 include_once 会返回 true
include_once("文件.php")

文件操作

文件操作函数

// 文件
fopen('文件名或url','打开模式')
fread('文件名','读取的最大字节数')
filesize('文件名')
fwrite('文件名','写入的内容')
copy('原文件','目标文件') // 如果目标文件已存在,将会被覆盖
rename('原文件名','新文件名')
unlink('原文件') // 删除文件
fclose($打开的文件变量)

// 目录
opendir('目录路径') // 打开一个目录,读取它的内容,然后关闭
readdir($打开的目录变量)
rmdir('目录路径')
mkdir('目录名','权限')
closedir($打开的目录变量)
scandir() // 返回指定目录中的文件和目录的数组

文件打开模式

正则表达式

$exp = "/toki/i";

toki 为要比配的正则表达式,i 为不区分大小写,界定符通常使用 /,也可以用 # ~ 代替

Function Description
preg_match($pattern, $str) 匹配到返回1,否则返回0
preg_match_all($pattern, $str) 返回匹配到的次数
preg_replace() 返回被替换的整个字符串
Modifier Description
i Performs a case-insensitive search
m Performs a multiline search (patterns that search for the beginning or end of a string will match the beginning or end of each line)
u Enables correct matching of UTF-8 encoded patterns
Metacharacter Description
| Find a match for any one of the patterns separated by | as in: cat|dog|fish
. Find just one instance of any character
^ Finds a match as the beginning of a string as in: ^Hello
$ Finds a match at the end of the string as in: World$
\d Find a digit
\s Find a whitespace character
\b Find a match at the beginning of a word like this: \bWORD, or at the end of a word like this: WORD\b
\uxxxx Find the Unicode character specified by the hexadecimal number xxxx
Quantifier Description
n+ Matches any string that contains at least one n
n* Matches any string that contains zero or more occurrences of n
n? Matches any string that contains zero or one occurrences of n
n Matches any string that contains a sequence of X n's
n Matches any string that contains a sequence of X to Y n's
n Matches any string that contains a sequence of at least X n's

preg_match()

<?php
$str = "Apples and bananas.";
$pattern = "/ba(na){2}/i";
echo preg_match($pattern, $str); // Outputs 1
?>

preg_match_all()

<?php
$str = "The rain in SPAIN falls mainly on the plains.";
$pattern = "/ain/i";
echo preg_match_all($pattern, $str); // Outputs 4
?>

preg_replace()

<?php
$str = "Visit Microsoft!";
$pattern = "/microsoft/i";
echo preg_replace($pattern, "W3Schools", $str); // Outputs "Visit W3Schools!"
?>

PHP 爬虫

file_get_contents() 和 file_put_contents()

// 把整个文件读入一个字符串中
file_get_contents('文件名或url')
// 把一个字符串写入文件中,写入模式有:FILE_USE_INCLUDE_PATH、FILE_APPEND、LOCK_EX
// 如果设置了 FILE_USE_INCLUDE_PATH,那么将检查 filename 副本的内置路径
// 如果设置了 LOCK_EX,那么将锁定文件
// 如果设置了 FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容
file_put_contents('文件名','字符串',写入模式)

Note:如果要打开有特殊字符的 URL,就需要使用 urlencode() 进行 URL 编码。

file_get_contents() 函数超时处理

在使用 file_get_contents 函数读取文件或URL的时候,经常会出现超时的情况,我们可以通过一些方法来尽量的避免或者解决。

增加超时的时间限制

这里需要注意:set_time_limit(0) 只是设置你的PHP程序的超时时间,而不是 file_get_contents 函数读取URL的超时时间。

想通过 set_time_limit(0) 影响到 file_get_contents 来增加超时时间,经测试,是无效的。真正的修改 file_get_contents 延时可以用 resource $contexttimeout 参数,timeout 参数的单位是 s(秒)。

实例:

$opts = array( 
    'http'=>array( 
        'method'=>"GET", 
        'timeout'=>30, 
    ) 
); 
$html = file_get_contents('http://www.baidu.com', false, stream_context_create($opts)); 
echo $html;

超过几秒就重新执行,多次重试直到成功

file_get_contents 超时有时候失败是因为网络等因素造成,没有解决办法,但是可以修改程序,失败时重试几次,仍然失败就放弃,因为 file_get_contents() 如果失败将返回 FALSE,所以可以下面这样编写代码:

$cnt=0; 
while($cnt < 3 && ($str=@file_get_contents('http://www.w3cschool.cn'))===FALSE) $cnt++;

注意:如果执行时间过长,还需要用函数 set_time_limit(0); 就不会超时了。

file_get_contents() 函数代理设置处理

设置代理 IP 去获取页面数据

$context = array( 
    'http' => array( 
        'proxy' => 'tcp://192.168.0.1:3128',	//这里设置你要使用的代理ip及端口号 
        'request_fulluri' => true, 
    ), 
    'ssl' => array(
		"verify_peer" => false,					// 取消ssl验证
		"verify_peer_name" => false
	),
); 
$context = stream_context_create($context); 
$html = file_get_contents("http://www.baidu.com", false, $context); 
echo $html;

设置需要验证的代理 IP 去采集获取页面数据

$auth = base64_encode('USER:PASS');   //LOGIN:PASSWORD 这里是代理服务器的账户名及密码 
$context = array( 
    'http' => array( 
        'proxy' => 'tcp://192.168.0.1:3128',  //这里设置你要使用的代理ip及端口号 
        'request_fulluri' => true, 
        'header' => "Proxy-Authorization: Basic $auth",
    ), 
); 
$context = stream_context_create($context); 
$html = file_get_contents("http://www.baidu.com", false, $context); 
echo $html;

超全局变量

$GLOBALS["变量名"] 	存放所有全局变量的数组,可全局调用
$_SERVER		服务器信息变量,该全局变量包含着服务器和客户端配置及当前请求环境的有关信息
    $_SERVER['SERVER_NAME'] - 当前运行脚本所在的服务器的主机名
    $_SERVER['REMOTE_ADDR'] - 客户端 IP 地址
    $_SERVER['REQUEST_URI'] - URL 的路径部份
    $_SERVER['HTTP_USER_AGENT'] - 操作系统和浏览器的有关信息
    $_SERVER["PHP_SELF"] - 返回当前正在执行脚本的文件名
    $_SERVER["REQUEST_METHOD"] - 检测表单是否被提交,返回POST或空
$_FILES			与上传文件有关的变量数组
    <input type="file" name="userfile">
    $_FILES['userfile']['name'] - 上传文件的名称
    $_FILES['userfile']['type'] - 上传文件的类型
    $_FILES['userfile']['size'] - 上传文件的大小,以字节计
    $_FILES['userfile']['tmp_name'] - 存储在服务器的文件的临时副本的名称
    $_FILES["file"]["error"] - 由文件上传导致的错误代码
$_REQUEST 		用来收集通过 GET 和 POST 等方法发送的表单数据
$_GET 			用于收集来自 method="get" 的表单中的值,是一个数组,大小不能超过 2000 个字符
$_POST 			用于收集来自 method="post" 的表单中的值,$_POST 也常用于传递变量,大小没有限制
$_ENV			环境变量
$_COOKIE 		存放 cookie 变量的数组
$_SESSION 		存放 session 变量的数组

$_SERVER

Element/Code Description
$_SERVER['PHP_SELF'] Returns the filename of the currently executing script
$_SERVER['GATEWAY_INTERFACE'] Returns the version of the Common Gateway Interface (CGI) the server is using
$_SERVER['SERVER_ADDR'] Returns the IP address of the host server
$_SERVER['SERVER_NAME'] Returns the name of the host server (such as www.w3schools.com)
$_SERVER['SERVER_SOFTWARE'] Returns the server identification string (such as Apache/2.2.24)
$_SERVER['SERVER_PROTOCOL'] Returns the name and revision of the information protocol (such as HTTP/1.1)
$_SERVER['REQUEST_METHOD'] Returns the request method used to access the page (such as POST)
$_SERVER['REQUEST_TIME'] Returns the timestamp of the start of the request (such as 1377687496)
$_SERVER['QUERY_STRING'] Returns the query string if the page is accessed via a query string
$_SERVER['HTTP_ACCEPT'] Returns the Accept header from the current request
$_SERVER['HTTP_ACCEPT_CHARSET'] Returns the Accept_Charset header from the current request (such as utf-8,ISO-8859-1)
$_SERVER['HTTP_HOST'] Returns the Host header from the current request
$_SERVER['HTTP_REFERER'] Returns the complete URL of the current page (not reliable because not all user-agents support it)
$_SERVER['HTTPS'] Is the script queried through a secure HTTP protocol
$_SERVER['REMOTE_ADDR'] Returns the IP address from where the user is viewing the current page
$_SERVER['REMOTE_HOST'] Returns the Host name from where the user is viewing the current page
$_SERVER['REMOTE_PORT'] Returns the port being used on the user's machine to communicate with the web server
$_SERVER['SCRIPT_FILENAME'] Returns the absolute pathname of the currently executing script
$_SERVER['SERVER_ADMIN'] Returns the value given to the SERVER_ADMIN directive in the web server configuration file (if your script runs on a virtual host, it will be the value defined for that virtual host) (such as someone@w3schools.com)
$_SERVER['SERVER_PORT'] Returns the port on the server machine being used by the web server for communication (such as 80)
$_SERVER['SERVER_SIGNATURE'] Returns the server version and virtual host name which are added to server-generated pages
$_SERVER['PATH_TRANSLATED'] Returns the file system based path to the current script
$_SERVER['SCRIPT_NAME'] Returns the path of the current script
$_SERVER['SCRIPT_URI'] Returns the URI of the current page

$_REQUEST

<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Name: <input type="text" name="fname">
  <input type="submit">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  // collect value of input field
  $name = $_REQUEST['fname'];
  if (empty($name)) {
    echo "Name is empty";
  } else {
    echo $name;
  }
}
?>

</body>
</html>

$_POST

<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Name: <input type="text" name="fname">
  <input type="submit">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  // collect value of input field
  $name = $_POST['fname'];
  if (empty($name)) {
    echo "Name is empty";
  } else {
    echo $name;
  }
}
?>

</body>
</html>

$_GET

<html>
<body>

<a href="test_get.php?subject=PHP&web=W3schools.com">Test $GET</a>

<?php
echo "Study " . $_GET['subject'] . " at " . $_GET['web'];
?>

</body>
</html>

header() 函数

作用:发送一个原始 HTTP 标头到客户端,服务器以 HTTP 协义传 HTML 到浏览器前所送出的字串,在 PHP 中送回 HTML 资料前,需先传完所有的标头。

内容类型

header('Content-Type: text/html; charset=utf-8'); //网页编码
header('Content-Type: text/plain'); //纯文本格式
header('Content-Type: image/jpeg'); //JPG、JPEG 
header('Content-Type: application/zip'); // ZIP文件
header('Content-Type: application/pdf'); // PDF文件
header('Content-Type: audio/mpeg'); // 音频文件 
header('Content-type: text/css'); //css文件
header('Content-type: text/javascript'); //js文件
header('Content-type: application/json');  //json
header('Content-type: application/pdf'); //pdf
header('Content-type: text/xml');  //xml格式文件

页面功能

header('HTTP/1.1 200 OK');  // ok 正常访问
header('HTTP/1.1 301 Moved Permanently'); //设置地址被永久的重定向 301
header('HTTP/1.1 304 Not Modified'); //告诉浏览器文档内容没有发生改变
header('HTTP/1.1 404 Not Found'); //通知浏览器 页面不存在
header('Location: http://www.ithhc.cn/'); //重定向到一个新的地址
header('Refresh:10; url=http://www.baidu.cn/'); //延迟跳转
header('X-Powered-By: PHP/6.0.0'); //修改 X-Powered-By 信息
header('Content-language: en'); //文档语言
header('Content-Length: 1234'); //设置内容长度
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT'); //告诉浏览器最后一次修改时间

数据传输

传值

form 表单 - <form method="GET"></form>
a 标签 - <a href="blog.toki.plus?name=toki">
href 属性 - <script>location.href="blog.toki.plus?name=toki"</script>
assign() 方法 - <script>location.assign("blog.toki.plus?name=toki")</script>
  • window.location.href:返回当前页面 url
  • window.location.hostname:返回网站域名
  • window.location.pathname:放回当前 url 的相对路径
  • window.location.protocol:返回网页端口号
  • window.location.assign("新的 url"):加载新的页面

取值

GET - $name = $_GET["username"];
POST - $name = $_POST["username"];

表单写法

<form method="POST" enctype="multipart/form-data" action="test.php"></form>
    
method 属性 - 表单提交方式必须为 POST
enctype 属性 - form 表单属性,主要是规范表单数据的编码方式
	- application/x-www-form-urlencoded 	在发送前编码所有字符(默认)
	- multipart/form-data					不对字符编码,包含文件上传的表单必须使用该值
	- text/plain							空格转换为“+”加号,但不对特殊字符编码
(可以在表单中添加 MAX_FILE_SIZE 隐藏域,通过设置其 value 值可以限制上传文件的大小)

文件上传校验

// 检查指定的文件是否是通过 HTTP POST 上传的
// 该函数的结果会被缓存。请使用 clearstatcache() 来清除缓存
bool is_uploaded_file(string filename)
// 把上传的文件移动到新位置
bool move_uploaded_file(string filename, string destination)

Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

  1. 安全性
    Session:存储服务器端,安全性高
    Cookie:存储浏览器端,安全性低
  2. 数据大小
    Cookie:的数量和大小都有限制
    Session:数据存储不限
  3. 可用数据类型
    Cookie:只能存储简单数据,数值 字符串
    Session:可以存储复杂数据(自动序列化)
  4. 保存位置
    Cookie:保存在浏览器上
    Session:保存在服务器上
  • setcookie("字段", "值", 生命周期, "存放路径", "有效域名", 是否只允许https, 是否不允许脚本访问);

时间戳:默认为 0,代表浏览器关闭就删除 cookie
存放路径:父目录中设置过的 cookie 可以在子目录中获取到,反之不行,一般用 '/'

增/改 - setcookie("name", "Toki", time()+60*60*24*30);
删 - setcookie("name", "", time()-3600);
   - unset($_COOKIE['name']);
查 - if (isset($_COOKIE["name"]));

判断是否已设置了cookie - isset($_COOKIE["name"])

设置 Session

  • session_set_cookie_params(lifetime, path, domain, secure, httponly):在调用 session_start() 函数之前调用,PHP 7.3 版本以上才有效

  • session_start():启动会话,必须位于 <html> 标签之前

  • unset($_SESSION["name"])

  • $_SESSION = array()

  • session_unset() 释放当前在内存中已经创建的所有 $_SESSION 变量,但不删除 session 文件以及不释放对应的 session id

  • session_destroy():删除当前用户对应的 session 文件以及释放 session id,内存中的 $_SESSION 变量内容依然保留

增/改 - $_SESSION["name"] = "Toki";
删 - unset($_SESSION["name"]); 或 session_destroy();
查 - if(isset($_SESSION['name']));
判断 - isset($_SESSION['name']))

常用过滤条件

if ($_POST) {}
if (!isset($_SESSION['']) || empty($_SESSION[''])) {}
if ($_FILES['']['error'] == 1-7) {}
if (!in_array('字符串', '数组')) {}
if (!is_dir('路径')) {}
if (file_exists($upload_path)) {}
if (is_uploaded_file($tmp_name)) {}
if (move_uploaded_file($tmp_name, $img_path)) {}

$_FILES['']['error']

  1. UPLOAD_ERR_OK
    其值为 0,没有错误发生,文件上传成功。

  2. UPLOAD_ERR_INI_SIZE
    其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize选项限制的值。

  3. UPLOAD_ERR_FORM_SIZE
    其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。

  4. UPLOAD_ERR_PARTIAL
    其值为 3,文件只有部分被上传。

  5. UPLOAD_ERR_NO_FILE
    其值为 4,没有文件被上传。

  6. UPLOAD_ERR_NO_TMP_DIR
    其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。

  7. UPLOAD_ERR_CANT_WRITE
    其值为 7,文件写入失败。PHP 5.1.0 引进。

数据库连接

面向对象

  • 类的变量用 var 声明

  • 类的常量用 const 声明,常量不需要用$符

  • 静态、常量、重写的属性与方法 调用:::

  • 对象的属性与方法 调用:->

  • 类:Class

  • 继承:extends

  • 接口:interfaceimplements

  • this关键字:$this -> name

  • 构造函数:__construct() - 实例化对象时自动调用

  • 析构函数:__destruct() - 对象被释放时自动调用

  • 访问修饰符:public(默认)privateprotected

算法

冒泡排序

<?php
    $numbers = [9,8,7,6,5,4,3,2,1,0];
    bubble($numbers);

    function bubble($numbers){
        // 冒泡的轮数
        for($round=0; $round<count($numbers)-1; $round++){
            // 两两比较的次数
            for($index=0; $index<count($numbers)-1-$round; $index++){
                if($numbers[$index]>$numbers[$index+1]){
                    $tmp = $numbers[$index];
                    $numbers[$index] = $numbers[$index+1];
                    $numbers[$index+1] = $tmp;
                }
            }
        }
        foreach ($numbers as $number) {
            echo $number;
        }
    }
?>
posted @ 2022-02-28 22:39  toki-plus  阅读(129)  评论(0编辑  收藏  举报