MAMP-1
书籍:《PHP、MySQL与JavaScript学习手册》第四版
开始于第三章(๑•̀ㅂ•́)و✧
0x01 关于PHP
-
标记符:以下两种均可以;但后者与XML不兼容,不提倡。
1
2
3
echo "Hello world";1
2
3
echo "Hello world"; -
注释:多行注释不能嵌套。
1
2
3
4
5
6
7
8
9
//This is a comment
echo "COMMENT";
/*
This
is
a
comment */ -
PHP是由C和Perl发展而来的,多类比C,有助于学习。
-
变量名大小写敏感。
-
.
运算符是连接 -
逻辑运算符
运算符 说明 && 与 and 低优先级与 || 或 or 低优先级或 ! 非 xor 异或 -
自增自减运算和C语言相同。
-
字符串:单引号是直接输出,也无法实现转义的功能。
1
2
3
4
5
$j = 13;
echo 'This is $j';
echo "This is $j"; //双引号替换变量值 -
多行字符串输出或赋值
1
2
3
4
5
6
7
8
9
$author = "Bill Gates";
$text = "Measuring programming progress by lines of code is like
Measuring aircraft building progress by weight.
- $author.";
1
2
3
4
5
6
7
8
9
10
11
12
13
$author = "Brian W. Kernighan";
//标签可以自己指定,但开始和结束相同,例如:_Start、Start等
//开始标签后续不能添加其他信息
echo <<<_END
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it.
- $author.
_END;
//关闭的_END 标签必须单独一行 -
弱语言类型
1
2
3
4
5
6
7
8
$number = 1234*567;
echo substr($number,3,1);
echo "\n";
$pi = "3.1415927";
$radius = 5;
echo $pi * ($radius * $radius);结果:
1
2
3lowbee 3 $php example3-11.php
6
78.5398175 -
常量
1
2
3
define("ROOT_LOCATION","/usr/local/www/");//define 定义
$directory = ROOT_LOCATION; //使用常量不需要$ -
echo & print
两者均是PHP的结构,不需要使用括号。
echo:多个参数、不是函数,没有返回值,运行更快一些,不能作为复杂表达式的一部分
print:一个参数、返回值是1,能作为复杂表达式的一部分
-
变量作用域
全局变量 静态变量 超级全局变量 所有函数都可以使用的变量 函数内部多次使用的,变量值和调用次数有关的 预定义变量,包含程序的信息和环境等 global $logged_in; function test(){
static $count = 0;
…
}$GLOBALS :全部的全局变量
$_GET:GET方式获取的变量
$_POST:POST方法获取的变量
$_COOKIE:会话变量
… -
htmlentities
函数对用户传入的参数消毒==>将所有的字符转成html实体,例:<
==><
0x02 PHP中的表达式和控制流
-
TRUE和FALSE是PHP中预定义的变量,可以用小写,而且小写更稳定,不允许被重新定义。
1
2
3
4
5
6
echo "a: [" . (20 > 9) . "]<br>";
echo "b: [" . (5 == 6) . "]<br>";
echo "c: [" . (1 == 0) . "]<br>";
echo "d: [" . (1 == 1) . "]<br>";结果如下:在PHP中FALSE被定义为NULL
1
2lowbee 4 $php example4-1.php
a: [1]<br>b: []<br>c: []<br>d: [1]<br> -
多重赋值语句
1
2
3
$a = $b = $c =0; -
一致性运算符
===
会阻止PHP进行自动的类型转换。 -
条件语句
-
if…elseif…else
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if ($bank_balance < 100)
{
$money = 1000;
$bank_balance += $money;
}
elseif ($bank_balance > 200)
{
$savings += 100;
$bank_balance -= 100;
}
else
{
$savings += 50;
$bank_balance -= 50;
} -
switch…case
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
switch ($page)
{
case "Home":
echo "You selected Home";
break;
case "About":
echo "You selected About";
break;
case "News":
echo "You selected News";
break;
case "Login":
echo "You selected Login";
break;
case "Links":
echo "You selected Links";
break;
default:
echo "Unrecognized selection";
break;
}1
2
3
4
5
6
7
8
9
10
11
12
13
switch ($page):
case "Home":
echo "You selected Home";
break;
// etc...
case "Links":
echo "You selected Links";
break;
endswitch; -
三目运算符:
? :
1
2
3
echo $fuel <= 1 ? "Fill tank now" : "There's enough fuel";
-
-
循环
-
while
-
do…while
-
for
1
2
3
4
5
6
7
8
9
10
11
12
$fp = fopen("text.txt", 'wb');
for ($j = 0 ; $j < 100 ; ++$j)
{
$written = fwrite($fp, "data");
if ($written == FALSE) break;
}
fclose($fp); -
break跳出循环:也可以自己指定跳出多少层循环,如
break 2;
跳出两层循环。 -
continue:结束当前一次循环。
-
0x03 PHP函数与对象
-
phpinfo()
-
三个字符串函数
1
2
3
4
5
echo strrev(" .dlrow olleH"); // Reverse string
echo str_repeat("Hip ", 2); // Repeat string
echo strtoupper("hooray!"); // String to upper case -
函数名大小写不敏感,但变量名敏感。
-
函数被定义前调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$a1 = "WILLIAM";
$a2 = "henry";
$a3 = "gatES";
echo $a1 . " " . $a2 . " " . $a3 . "<br>";
fix_names();
echo $a1 . " " . $a2 . " " . $a3;
function fix_names()
{
global $a1; $a1 = ucfirst(strtolower($a1));
global $a2; $a2 = ucfirst(strtolower($a2));
global $a3; $a3 = ucfirst(strtolower($a3));
}首先PHP不是单纯的按照行来边du解释边执行的,而是先由Zend引擎翻译PHP代码到zhiZend二进制操作码,然后dao再去执行操作码。对于function的位置,因为函数的作用域是全局的,所以只要定义了,那么就可以在任意位置去调用它。但是除了两种情况,函数必须在其调用之前定义,一是在条件语句中定义的函数,二是在函数中定义的函数。
-
PHP 5.4之后不再支持传参时传引用
-
包含和请求文件
函数 说明 include 将文件试图导入,即便文件没有被找到,程序继续执行、不会报错。遇到一次,导入一次,会导致文件包含的嵌套问题,即:a包含b、c,b包含c。 include_once 也是将文件试图导入。但导入前会检查文件是否被包含,若包含、跳过此命令。推荐使用。 require 强制文件导入,导入失败程序会停止执行、并报错。遇到一次,请求包含一次。 require_once 同include_once,会检查文件是否已经被包含。推荐使用。 -
版本兼容问题:查看函数是否存在
1
2
3
4
5
6
7
8
9
10
if (function_exists("array_combine"))
{
echo "Function exists";
}
else
{
echo "Function does not exist - better write our own";
} -
类定义包括类名(大小写敏感)、属性及方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$object = new User;
print_r($object); //_r代表按照常规阅读规格
class User
{
public $name, $password;
function save_user()
{
echo "Save User code goes here";
}
}结果:命令行结果如下,浏览器输出会忽略所有空格。
1
2
3
4
5User Object
(
[name] =>
[password] =>
) -
对象克隆
- 以下是错误用例,$object1 与$object2均指向同一对象,并未实现对象复制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$object1 = new User();
$object1->name = "Alice";
$object2 = $object1;
$object2->name = "Amy";
echo "object1 name = " . $object1->name . "<br>";
echo "object2 name = " . $object2->name;
class User
{
public $name;
}- 以下是正确姿势:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$object1 = new User();
$object1->name = "Alice";
$object2 = clone $object1; //====> 克隆对象
$object2->name = "Amy";
echo "object1 name = " . $object1->name . "<br>";
echo "object2 name = " . $object2->name;
class User
{
public $name;
} -
构造方法:方法1==>方法2
1
2
3
4
5
6
7
8
9
10
//方法1
class User
{
function User($param1, $param2)
{
// Constructor statements go here
}
}1
2
3
4
5
6
7
8
9
10
//方法2
class User
{
function __construct($param1, $param2)
{
// Constructor statements go here
}
} -
PHP5 析构方法
1
2
3
4
5
6
7
8
9
class User
{
function __destruct()
{
// Destructor code goes here
}
} -
类的静态方法
1
2
3
4
5
6
7
8
9
10
11
User::pwd_string();
class User
{
static function pwd_string()
{
echo "Please enter your password";
}
} -
类中不必直接(显示)声明属性,但不提倡
1
2
3
4
5
6
7
8
$object1 = new User();
$object1->name = "Alice";
echo $object1->name;
class User {} -
声明常量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Translate::lookup();
class Translate
{
const ENGLISH = 0;
const SPANISH = 1;
const FRENCH = 2;
const GERMAN = 3;
// ...
static function lookup()
{
echo self::SPANISH;
}
} -
对象不能直接访问静态属性或常量
-
继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$object = new Subscriber;
$object->name = "Fred";
$object->password = "pword";
$object->phone = "012 345 6789";
$object->email = "fred@bloggs.com";
$object->display();
class User
{
public $name, $password;
function save_user()
{
echo "Save User code goes here";
}
}
class Subscriber extends User //===>继承
{
public $phone, $email;
function display()
{
echo "Name: " . $this->name . "<br>";
echo "Pass: " . $this->password . "<br>";
echo "Phone: " . $this->phone . "<br>";
echo "Email: " . $this->email;
}
}-
parent运算符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$object = new Son;
$object->test();
$object->test2();
class Dad
{
function test()
{
echo "[Class Dad] I am your Father<br>";
}
}
class Son extends Dad
{
function test()
{
echo "[Class Son] I am Luke<br>";
}
function test2()
{
parent::test();
//若指明当前类的方法,可以使用 self::method(),即self::test()
}
} -
Final方法:防止子类方法覆盖父类方法
1
2
3
4
5
6
7
8
class User
{
final function hello()
{
echo "This is hello of son, not dad.";
}
}
-
0x04 PHP的数组
1.数值数组
不推荐方法1,难以维护数组,推荐使用方法2。
1 |
|
1 |
|
2.关联数组
通俗易懂,就是Python的字典。
1 |
|
1 | lowbee 6 $php example6-5.php |
-
循环遍历数组:foreach…as
1
2
3
4
5
6
7
8
9
10
$paper = array("Copier", "Inkjet", "Laser", "Photo");
$j = 0;
foreach($paper as $item)
{
echo "$j: $item<br>";
++$j;
}1
2
3
4
5
6
7
8
9
$paper = array('copier' => "Copier & Multipurpose",
'inkjet' => "Inkjet Printer",
'laser' => "Laser Printer",
'photo' => "Photographic Paper");
foreach($paper as $item => $description)
echo "$item: $description<br>"; -
循环遍历:list()和each()
1
2
3
4
5
6
7
8
9
$paper = array('copier' => "Copier & Multipurpose",
'inkjet' => "Inkjet Printer",
'laser' => "Laser Printer",
'photo' => "Photographic Paper");
while (list($item, $description) = each($paper))
echo "$item: $description<br>";
3.多维数组
1 |
|
4.数组函数
-
is_array()
-
count()
:顶层元素数量 -
sort()
:排序,rsort()
反序排列-
sort()
直接在数组上排序 -
sort($a,SORT_NUMERIC)
按照数值排序 -
sort($a,SORT_STRING)
按照字符串排序
-
-
shuffle($cards)
对数组随机排序 -
explode()
:按照指定分隔符,切分字符串为数组1
2
3
4
$temp = explode(' ', "This is a sentence with seven words");
print_r($temp);1
2
3
4
5
6
7
8
9
10Array
(
[0] => This
[1] => is
[2] => a
[3] => sentence
[4] => with
[5] => seven
[6] => words
)1
2
3
4
$temp = explode('***', "A***sentence***with***asterisks");
print_r($temp);1
2
3
4
5
6
7Array
(
[0] => A
[1] => sentence
[2] => with
[3] => asterisks
) -
extract()
:将关联数组的键值对转成变量=值
的形式常用于将$_GET与$_POST,用法:
1
2extract($_GET);//普通用法
extract($_GET,EXTR_PREFIX_ALL,'fromget');//变量名都有前缀fromget,防止变量名的重复而覆盖 -
compact()
:作用与extract()
相反1
2
3
4
5
6
7
8
9
10
11
$fname = "Doctor";
$sname = "Who";
$planet = "Gallifrey";
$system = "Gridlock";
$constellation = "Kasterborous";
$contact = compact('fname', 'sname', 'planet', 'system', 'constellation');
print_r($contact);1
2
3
4
5
6
7
8Array
(
[fname] => Doctor
[sname] => Who
[planet] => Gallifrey
[system] => Gridlock
[constellation] => Kasterborous
) -
reset()
:循环遍历过程中,将指向下一个元素的指针指向数组开始。1
2reset($a);//丢弃返回值
$item = reset($a);//在$item中保存数组中第一个元素 -
end()
1
2end($a);//将数组指针移动到最后
$item = end($a);//在$item中保存数组最后的元素
0x05 实用PHP技术
1.打印格式
printf()
比print
和echo
的强大之处在于,格式化输出格式,常见的数字转换、控制精度、填充字符等;和C语言中的 printf()
极为相似。sprintf()
可以将打印结果存在变量中,不用输出至浏览器。
2.时间格式
使用UNIX的时间戳,按秒数存储。
1 | echo time(); //当前时间戳 |
由于时间戳只能到2038年,因此会出现Y2K38漏洞,在PHP5.2 引入DateTime类解决问题,仅在64位计算机。
1 |
|
3.文件操作
Windows和MacOS X对文件命名大小是不敏感的,Linux和Unix是敏感的。区分大小写是好习惯。
- 文件写
1 | //文件写操作 |
- 文件读
1 | //文件读操作 |
- 复制、移动、删除
1 | //使用前最好用file_exists()检查文件是否存在 |
- 文件更新
1 | //更新文件 |
说明:不是所有的文件系统都支持文件加锁。
fseek()
参数说明:
- 第一参数$fh:指处理的文件
- 第二参数:文件内部指针偏移量,记为n。
- 第三参数:
- SEEK_END:从文件末尾往前偏移n位
- SEEK_SET:指向n的位置
- SEEK_CUR:在当前基础上往后偏移n位
- 简易读取
1 | echo file_get_contents("testfile.txt"); //简单明了的读取文件全部内容 |
- 文件上传
1 |
|
假设提交表单时文件名为 file
,前端定义的文件名:
数组元素 | 内容 |
---|---|
$_FILES[‘file’][‘name’] | 上传文件名 |
$_FILES[‘file’][‘type’] | 文件类型(如image/jpeg) |
$_FILES[‘file’][‘size’] | 文件大小(字节) |
$_FILES[‘file’][‘tmp_name’] | 临时服务器上的文件名 |
$_FILES[‘file’][‘error’] | 错误代码 |
4.系统调用
exec()
函数的使用。
1 |
|
$status保存运行状态
$output保存返回结果
escapeshellcmd():转义存在欺骗的字符。
反斜线(\)会在以下字符之前插入: *&#;`|*?~<>^()[]{}$*, \x0A 和 \xFF。 ’ 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。