[苏勇和他的 IterCast](https://www.zhihu.com/question/23871761/answer/25926171)。
学习环境:[runphponline](http://www.runphponline.com/?filename=php_default) 或 [anycodes](http://www.anycodes.cn/zh)。
- PHP学院 - phpxy.com
此站教程、手册齐全。
- 7天学会PHP - phpbook.phpxy.com
简明扼要。**看云上可以下载三种格式的电子书。**
> **对应短小精悍的视频教程**:http://www.mobiletrain.org/video/php_download.html
- 李炎恢 HTML CSS JavaScript PHP Bootstrap
kancloud.cn/wizardforcel/liyanhui-tutorials/154156
==========
- 市场分析
目前PHP在全球网页市场、手机网页市场还有为手机提供API(程序接口)排名第一。
在中国微信开发大量使用PHP来进行开发。
- 我们把我们写代码的软件和运行代码的软件统一的称为开发环境。
时间宝贵,环境只要能满足学习要求即可。
- 所谓服务器:不要把它想的太过于高深,不过就是提供一项特殊功能(服务)的「电脑」而已。
显示网页的叫网页(web)服务器(server)。
帮我们代为收发电子邮件(email)的服务器叫邮件服务器。
帮我们把各个游戏玩家连接在一起的叫游戏服务器。
帮我们存储数据的叫数据库服务器。
> 所谓的 “\*\*服务器” 就是一台长期开机、可以访问的装有对应功能软件的电脑。
- 网页服务器、数据库服务器和PHP最核心的语法解释器。
强烈建议初学者使用集成环境包(XAMPP)。
_我还是使用 vagrant 吧。_
- htdocs。
- http://127.0.0.1
- 选择编辑器的标准:不带提示,要有高亮。(Notepad++)
- 一看就懂,一写就错。
> **永远不要骗自己,写不出来代码就是不会。**
==================================================
- 第一段PHP代码。
~~~
<?php //从此处【尖括号、问号、PHP】这5个字符开始,往下的部份是PHP代码
phpinfo(); // 一行代码写完,就必须要加分号
?> // 遇到上面的【问号、尖括号】说明PHP代码写完了。再之后的部份,跟我PHP没有关系啦
~~~
- 源码文件命名不要用中文,不要用特殊符号,不要中间加空格,严格区分大小。
(a-zA-Z0-9_-)
- 变量。
以$开始,首非数字,大小敏感,禁止中文。
下划线不算特殊符号。
> 符号读法:3\#井,4$刀,7&与,8\*星。
> 所谓“三井,四刀,七与,八星”。
- echo 是在PHP里面最常用的一个输出、显示功能的命令。
- 注释
~~~
// 表示单行注释
/*
* 多行注释 这里是注释区域代码
*/
~~~
- 没赋值的变量。变量值为空NULL。
- 字符串声明
用单引号
用双引号
用字界符(需要输入非常大段的字符串时使用)
~~~
<?php
$dingjie = <<<ABC
如果
非要在这个滚犊子
前
面<br />
加上一段
<i>距离的话</i>
我想说:<h1>思想有多远,你就跟我滚多远</h1>
ABC;
?>
~~~
- **双引号解析变量,但是单引号不解析变量。**
在双引号里面插入变量,变量后面如果有英文或中文字符,它会把这个字符和变量拼接起来,【视为一整个变量】。
一定要在变量后面接上特殊字符,例如空格、!等分开。
如果在双引号里面插变量的时候,后面不想有空格,可以拿【大括号】将变量包起来。
双引号解析转义字符,单引号不解析转义字符。但,单引号能解析\' 和\
单引号效率高于双引号,**【尽可能使用单引号】**
双引号需要解析变量,因此双引号的效率没有单引号高。我们如果为了更高的效率,我们通常使用单引号。
双号和单引号可以互插!!!双引号当中插入单引号,单引号当中插入变量,这个变量会被解析。
神奇的字符串拼接胶水——**(.)点,用来拼接字符串。**
echo $shixi . $buran . $mimang . $xuexi;
因此,大括号的用法还是尽量少用,尽量使用字符串连接的方式比较好。
我们将定界符声明字符串视为双引号一样的功能来看待。
- 不可见字符:主要是计算机规定的一些特殊符号。例如:回车(\n)、缩进(\t)等。
双引号执行变量,所以……
- 浮点数。
php使用变量不用声明,直接 $变量名 = 值。
- var_dump() 是一个函数。向括号()中间插入变量。这个函数,会打印出来数据类型,还会对应显示变量的长度和值。
- if () {}
else {}
一句话的时候可以不写大括号,但是规范。
- 空在英文里面表示是null,它是代表没有。空(null)不是false,不是0,也不是空格。
【重点】知道null产生的三种情况,学习empty 和 isset两个函数的区别。
主要有以下三空情况会产生空(null)类型:
通过变量赋值明确指定为变量的值为NULL
一个变量没有给任何值
使用函数unset()将变量销毁掉
- empty()可以向括号中间传入一个【变量】,字面量不行。
这个变量的值如果为false或者为null的话,返回true。
否则返回false。
$four = 1;
var_dump(empty($four));
[注] 判断【变量】是否为空。
- isset()可以向括号中间传入一个或者多个【变量】,变量与变量间用逗号分开。
只要有一个变量为null,则返回false。
$four = null;
var_dump(isset($four));
否则,则返回true。
[注] 判断【变量】是否被赋值
- unset()这个函数的功能是毁掉变量。
- 对象是一个复合类型。var_dump一个变量的时候看到的类型为object的,这个变量就是对象类型。
- 数组是一个复合类型。var_dump一个变量的时候看到的类型为array的,这个变量就是数组类型。
数组声明。
$a = array(1,2,3);
var_dump($a);
- 资源。抽象。
电脑里面的资源是指:
word,excel等文件
有人收藏的美女图片和我们的自拍照片等图片
音乐
某些人爱看的AVI小电影
打开的网页
数据库
... ...
我们打开一个图片,用PHP来操作它,我们就是操作的一个资源。
我们打开的数据库**连接(就是你拽着的一条绳子,我们把这个也抽象成了资源,称作“连接”)**,我们需要连接数据库,数据库就是我们操作的资源。
包括网络连接,连接后发送邮件,我们也可以认为是一个资源。
本章重点:理解资源就提操作我们可见和不可见的文件、网络和数据。
我们在以后的章节中,操作图片和网络的时候大家会有更为深刻的印象。
- 回调。
callback,英文中的call是叫,back是返回,回来的意思。
callback 汉译过来的意思即为:回调。(执行完成,再调一次某个功能执行一次)
我们在讲解函数类型和对象的时候,我们会演示讲解回调函数。
Ajax 的异步。Ajax 是一种理念而非技术,这种理念是通过浏览器的内置对象支持实现的。
- gettype(传入一个变量) 能够获得变量的类型。
var_dump(传入一个变量) 输出变类型和值。
判断数据类型使用 is_* 系列函数。
is_int 是否为整型
is_bool 是否为布尔
is_float 是否是浮点
is_string 是否是字符串
is_array 是否是数组
is_object 是否是对象
is_null 是否为空
is_resource 是否为资源
is_scalar 是否为标量
is_numeric 是否为数值类型
is_callable 是否为【函数】
- 标量:整型(int) 浮点(float)、【布尔(bool)】、字符串(string)
混合类型: 数组(array)、对象(object)
特殊类型:空(null)、 资源(resouce)、回调(callback)
//换成echo,is_int试试,为什么echo执行假区间呢?
if(is_callable('var_dump')){
echo '执行真区间';
}else{
echo '执行假区间';
}
为什么最后的实验中 echo 执行假区间呢?
答:因为「echo」不是函数,「是基本语法」。大家眼前可以不用理解函数和基本语法的区别。了解和不了解在实际开发中没有影响。知道有这个知识点就行。
- PHP 7 的性能与 PHP5.6 相比,提升了性能接近 200%。
7中有些地方,我们可以强制指定类型,也可以不用强制指定类型来声明变量。
5.x 阶段都是完全的弱类型的编程语言。
- 自动类型转换,就是数据类型在某些情况下,自动会变为其他的类型参与运算。
自动类型转换的发生时机是:运算和判断的时候某些值会自动进行转换。
- 布尔值判断时的自动类型转换:
1. 整型的0为假,其他整型值全为真
2. 浮点的0.0,布尔值的假。小数点后只要有一个非零的数值即为真
3. 空字符串为假,只要里面有一个空格都算真
4. 字符串的0,也将其看作是假。其他的都为真
5. 空数组也将其视为假,只要里面有一个值,就为真
6. 空也为假
7. **未声明成功的资源也为假**
- 强制类型转换有三种方式:
1. 用后面的三个函数可以完成类型转换,intval()、floatval()、strval()
2. 变量前加上()里面写上类型,将它转换后赋值给其他变量
3. settype(变量,类型) 直接改变量本身
- 常——汉语字面为:长久,经久不变。
常量那就好翻译了:长久不变的值。
- define(常量名,常量值)
1. 常量值只能为上一章中我们讲到的标量**(不能用数组去赋值)**
2. 常量名可以小写,但是通常大写
3. 常量名可以不加引号,但是通常加上引号
4. 在字符串中调用常量的时候,必须在引号外面
5. 常量名建议只用字母和下划线
- 系统内置常量
LINE 当前所在的行
FILE 当前文件在服务器的路径
FUNCTIOIN 当前函数名
CLASS 当前类名
METHOD 当前成员方法名
PHP_OS PHP运行的操作系统
PHP_VERSION 当前PHP的版本
TRAIT Trait 的名字,php5.4新加
DIR 文件所在的目录
NAMESPACE 当前命名空间的名称(区分大小写)
- 为了防止其他人绕过安全检查文件。
~~~
<?php
//尝试将include 'version.php'这一行代码注释后再执行看看,对比结果
include 'version.php';
if(!defined('AUTH')){
echo '非法!非法!你尝试跳过授权文件';
exit;
}
//模拟后面用户注册和用户登陆的代码xxx行
echo '用户注册';
?>
~~~
- 可变变量其实就是——已声明的变量前,再上变量符。
~~~
<?php
$a = 'b';
$b = 'c';
echo $$a; // c
?>
~~~
- PHP 的外部变量是 PHP 在使用过程中规定好的一些变量。
这个变量的规定是这样规定的,就这样使用。
**其实就是一些PHP内置的小工具,被语言发明人在解释器里写好提供的。**
~~~html
<form action="reg.php" method="get">
<input type="text" name="username" />
<input type="password" name="pwd" />
<input type="submit" value="提交" />
</form>
~~~
把用户和密码,采用get方法,将数据发送给reg.php。
reg.php想办法接收用户传过来的username和pwd这两个值。
我们得出我们的第一个外部变量:**$_GET**。
$_GET 的主要作用是**拿到表单中get传值的数据。**
>$_GET后面加上中括号,将username作为字符串放在中括号里面,就得到了表单里面的`<input type="text" name="username" />` 的值。
~~~
<?php
$u = $_GET['username'];
echo $u.'<br />';
$passwd = $_GET['pwd'];
echo $passwd.'<br />';
?>
~~~
- 需要使用到post传值,post传值是在地址栏中不可见的。
PHP的代码里面的$_GET全改为了 **$_POST**。
通过我们看不见的浏览器的请求头文件传递的数据。所以在URL(网址)栏不可见。
- **$_REQUEST** 即可以接收get传值也可以接收post传值。
- 常用外部变量。(超全局变量)
$_COOKIE 得到会话控制中cookie传值
$_SESSION 得到会话控制中session的值
$_FILES 得到文件上传的结果
$_GET 得到get传值的结果
$_POST 得到post传值的结果
$_REQUEST 即能得到get的传值结果,也能得到post传值的结果
- firebug 可以在 post 的同时查看请求头的内容。查看header头传递数据(网络,点击POST reg.php 选择Post)。
若真是使用get传密码,密码在地址栏里面显示过后。浏览器的历史记录会自动记录访问过的地址。恶意用户会通过查看
你的浏览器的历史记录,得到你曾经输入的密码。因此,不能使用get方式来作密码的传输方式。
- chrome 的话,可以筛 method:POST,找到链接对应的 headers - form data。
- 环境变量。phpinfo();
和TCL察看当前文件的路径什么的,一个道理。
$_SERVER["**REQUEST_METHOD**"] 请求当前PHP页面的方法
$_SERVER["**REQUEST_URI**"] 请求的URI
$_SERVER["**SERVER_SOFTWARE**"] 用的是哪一种服务器
$_SERVER["**REMOTE_ADDR**"] 客户的IP地址
$_SERVER["**SERVER_ADDR**"] 当前服务器的IP地址
$_SERVER["**SCRIPT_FILENAME**"] 主前请求文件的路径
$_SERVER["**HTTP_USER_AGENT**"] 当前访问这个网址的电脑和浏览器的情况
$_SERVER["**HTTP_REFERER**"] 上级来源(用户从哪个地址进入当前网页的)
$_SERVER["**REQUEST_TIME**"] 当前的时间
- URL带有了主机地址部份,而URI不带协议和主机地址部份。
- url:http://www.phpxy.com/abc.php?username=liwenkai
- uri:abc.php?username=liwenkai
- 变量引用。vs 指针。
$bar = &$fo;
一个变量名,对应了一个数据值(空间)。
两个变量名,就对应两个数据值(空间)。
……
而加上&(and 符后),把变量指向同一个存值空间了。
**存的是地址?不是。直接变引用。和java一样,底层是指针,但是明面上你是读不到这个地址值的。**
也就是说 $bar 和 $fo 现在是指向同一个值空间。一间房子,原来只有一条路,现在又多了一条路,房子变了,从哪条路走都是走到这个房子来。
- %,取余,取模。
支持 += 和 .= 等快捷运算符。
支持自加自减。(关于先加后赋值$a=++$x 和 先赋值后加$a=$x++)
- 等于 ==(赋值是=号,所以==规定为等于)。
全等(也叫判断类型等于) ===
全不等(也叫判断类型不等于) !==
$x = 5;
$y = '5';
== true, === false。$x为整型,$y为字符串类型。
- 短路的用法。
~~~
<?php
//如果为defined('AUTH')存在AUTH常量则为true,不访问后面的exit了。如果为false则执行exit。
defined('AUTH') or exit('存在安全因素不准访问');
php>
~~~
- 位运算。左移乘2,右移除以2。对应十进制,左移乘10,右移除以10。
- 不用记优先级,确定不了的时候号上括号把优先级标出来即可。
- 其他运算符:
- $x? 真代码段(只能写一句代码):假代码段(只能写一句代码)。判断是否为真假 ? 真情况 : 假情况;
- \`\`(反引号) 反引号中间插代命令,执行系统命令,等价于shell_exec函数。echo \`ipconfig\`;(不过有些虚拟服务器是禁止执行这些的命令脚本的)
- @ 单行抑制错误,把这一行的错误不让它显示出来了,效率低不建议使用
- **=> 数组下标访问符**
- **-> 对象访问符**
- **instanceof 判断某个对象是否来自某个类,如果是的返回true,如果不是返回false**
- switch。
~~~
<?php
switch(变量){ //字符串,整型
case 具体值:
执行代码;
break;
case 具体值2:
执行代码2;
break;
case 具体值3:
执行代码3;
break;
default:
}
?>
~~~
可以不写 break 玩穿透。
- do...while... 有可能用在资源处理如:文件打开等地方。
- exit exit 之前我们讲过了,从当前处停止后续执行
break 之前遇到过,跳出循环或者跳出结构体执行后续代码
continue 跳出此次循环,下次循环继续
- PHP 5.3 起,可以使用 goto。通过标签实现。
- declare 在基础阶段,大家应该跳过此处学习。
- 函数的英文叫作:function,而 function 的解释项中有另外一个含义:功能。
函数 就是 功能。调用一个函数就是在调用一个功能。
函数是条狗,哪里需要哪里吼。
1. 需要用一个函数的时候,就吼一声它的名字。
2. 函数可以反复去吼,吼了它的名字它就过来了。也就是函数可以反复调用。
我们明白后,那我们接下来来讲解函数的分类,我们将函数分为两大类别:
1. 自定义函数
2. 系统函数
- 自定义函数。
~~~
function 函数名([参数名1[=值1], 参数名2[=值2], 参数名n[=值n]])
{
函数中的功能体
[return 返回值]
}
~~~
函数名与变量命名规则基本一样,但是不同的是:**函数名不区分大小写**。
**PHP 函数不能被重载**。[伪重载方案](http://www.jb51.net/article/65711.htm)。
- 函数体的参数若是定义了,未传参数,代码会报错。
但函数后的参数如果有默认值,参数可以不填,代码也不会报错。
函数后如果有默认值和无默认值的参数,通常把无默认值的参数写在最前面。
- **函数**的执行没有顺序关系,**可以在定义处之前的位置调用**。
这一点与 TCL 着实不同。
- 回调函数:在一个函数的参数里面,再传入一个函数名,将函数名加上()括号,识为变量函数,配合执行。
~~~
function woziji($one,$two,$func){
if(!is_callable($func)){
return false;
}
//$func是一个变量函数
echo $one + $two + $func($one,$two);
}
function plusx2( $foo , $bar){
$result = ($foo+$bar)*2;
return $result;
}
echo woziji(20,10,'plusx2');
~~~
- 变量部份,我们学习了可变变量($$a)。
可变函数仅仅是可变变量的一个变种、变形表达。
可变函数,我们也会称呼为变量函数。
> 核心思想就是一句话:函数也是一种变量类型。可变函数也是一种可变变量。
~~~
function demo(){
echo '天王盖地虎';
}
function test(){
echo '小鸡炖蘑菇';
}
$fu = 'demo';
//把$fu变为了demo,把demo后加上了一个括号,就执行函数了
$fu();
~~~
- 所谓匿名,就是没有名字。
匿名函数,也就是没有函数名的函数。
匿名函数的第一种用法,直接把赋数赋值给变量,调用变量即为调用函数。
1. 变量函数式的匿名函数
函数体没有函数名,通过$greent加上括号来调用的,这就是匿名函数。
~~~
$greet = function($name)
{
echo $name.',你好';
};
$greet('明天');
$greet('PHP学院');
~~~
2. 回调函数式的匿名函数
实际使用场景中,我们想通过一个函数实现一个功能。
但是,我又不想专门定义一个函数。
~~~
function woziji($one,$two,$func){
if(!is_callable($func)){
return false;
}
echo $one + $two + $func($one,$two);
}
woziji(20, 30, function($foo, $bar) {
$result = ($foo+$bar)*2;
return $result;
}
);
~~~
因此,函名函数在调用的时候没有函数名。
- 内部函数,是指在函数内部又声明了一个函数。
~~~
<?php
function foo()
{
echo '我是函数foo哟,调一下我才会执行定义函数bar的过程<br />';
function bar()
{
echo '在foo函数内部有个函数叫bar函数<br />';
}
}
//现在还不能调用bar()函数,因为它还不存在
bar();
foo();
//现在可以调用bar()函数了,因为foo()函数的执行使得bar()函数变为已定义的函数
bar();
//再调一次foo()看看是不是会报错?
foo();
?>
~~~
1. 内部函数名,不能是已存在的函数名。
2. foo()调用两次会报错。
3. 如果不调foo()函数无法执行bar函数,因为bar是在foo的内部。**(调了一下母函数,内部函数才算初次声明了)**
- 好像。
\`\`\` = <?
php = php
内容就是内容。
\`\`\` = ?>
- 变量作用域。
例外:超全局变量是外部变量,但在函数内部也是可以用。
$_COOKIE 得到会话控制中cookie传值
$_SESSION 得到会话控制中session的值
$_FILES 得到文件上传的结果
$_GET 得到get传值的结果
$_POST 得到post传值的结果
$_REQUEST 即能得到get的传值结果,也能得到Post传值的结果
- 通过 $GLOBLAS 在函数内创建、读取和修改外部变量(定义在函数外部的变量)。
- 在函数内使用global关键词后面跟一个或多个变量,就把变量变为了全局变量。我们越来越少的使用这种方式来声明全局变量了。**在TCL里还存在。**
- 函数的参数引用,也是这个意思,将形参和实参指向到同一个位置。如果形参在函数体内发生变化,那么实参的值也发生变化。(函数传参的“传引用”用法,vs “传参”)
- 递归函数。函数体内调用函数自己。主要是用在:文件和文件夹操作。
也可以用现成的文件和文件夹处理函数或文件处理类就可以。
>写出迭代公式,确定终止条件。
- 静态变量:函数被调用了多少次。
声明一个静态变量,第二次调用函数的时候,静态变量不再初始化变量,会在原值的基础上读取执行。
声明在函数内部,static $a = 0;
- 使用系统内置函数:依靠**手册**。
http://down.phpxy.com/book%2Fphp_enhanced_zh.chm
1. 了解函数的功能,特别是常用函数的功能
2. 了解函数的参数
3. 了解函数的返回值
- 返回 bool 值的,通常为操作是否成功、验证是否通过、检查是否正确等。
- int array_unshift ( array &$array , mixed $value1 [, mixed $... ] )
&符,引用传参。
Mixed 表示任何类型的数据,指可传入任意类型。
所有遇到中括号的。都是指后面的参数可传,也可以不传。
...(省略号)。代表可以传入任意多个参数。
~~~
<?php
$queue = array("凤姐", "芙蓉");
array_unshift($queue, "杨幂", "姚晨");
print_r($queue);
?>
~~~
- bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] )
~~~
$shuaige = array("a" => "wuyanzhu", "b" => "huangxiaoming", "c" => "ninzetao");
function test_print($item2, $key)
{
echo $key ." ---". strtoupper($item2) . "<br />\n";
}
echo '<pre>';
var_dump($shuaige);
echo '</pre>';
array_walk($shuaige, 'test_print');
echo '用自定义函数test_print执行后的效果:';
echo '<pre>';
var_dump($shuaige);
echo '</pre>';
~~~
- 系统函数支持的版本号很重要。
- 文件包含函数。**模块化编程。**
`如果被包含的 php 文件不存在:`
inlcude(返回一条警告) 文件继续向下执行。通常用于动态包含
require(一个致命的错) 代码就不会继续向下执行。通常包含极为重要的文件,整个代码甭想执行
include_once(返回一条警告) 除了原有include的功能以外,它还会做once检测,如果文件曾经已经被被包含过,不再包含
require_once(一个致命的错) 除了原的功能一外,会做一次once检测,防止文件反复被包含
- 所以,少用带once的,因为它会消耗更多的资源去做检测的工作。
- include 每次都会执行,同一个文件不能被包含两次,因为函数不能定义两次,否则会报错。
- require_once:包含的文件必须存在,否则停止执行。会做重复包含检查哟。
- 数学函数。看一遍知道PHP的数学函数里面为大家准备了这么多就可。
以后需要的时候,直接来用现查。
mt_rand():更好的随机数。
- 日期常用函数。要记录数据的地方就有时间。、
>[info] 我们为什么不直接用数据库里面的时间,因为在实际开发过程中,我们需要把时间取出来再排序和显示,所以单纯的用数据库里面的时间达不到我们的业务需求。
- 时区:1884年在华盛顿召开国际经度会议时,为了克服时间上的混乱,规定将全球划分为24个时区。在中国采用首都北京所在地东八区的时间为全国统一使用时间。
- 世界时:格林尼治时间(英文简写:GMT)。各地都有各地的地方时间。如果对国际上某一重大事情,用地方时间来记录,就会感到复杂不便。而且将来日子一长容易搞错。因此,天文学家就提出一个大家都能接受且又方便的记录方法,那就是以格林尼治(英国某地区)的地方时间为标准。
- Unix 时间戳:电脑本身不认识时间,我们在电脑里面设置一个时间方便运算。于是我们规定了一种计算方式,unix时间戳。从Unix纪元(1970 年 1月1日零时)开始到一个时间经过的秒数。
- echo date_default_timezone_get();
echo date_default_timezone_set(TIMEZONE);
http://php.net/manual/zh/timezones.php
- time()获取当前的unix时间戳。
- date函数用于将一个时间进行格式化输出,以方便时间的显示或存储。
>[success] date 函数的格式参数表。详见原书。
- getdate获取当前系统时间。
返回值是一个根据timestamp得到的**包含时间键值信息的数组**。如果没有参数,则会返回当前的时间。
- print_r可以输出一个数组中所有的键名与值。
- 日期验证函数。checkdate可以判断一个输出的日期是否有效。在实际的工作中,我们需要经常用于检测常用于用户提交表单的数据验证。
- mktime()。生成时间戳
- 程序执行时间检测,测试某个函数效率的快慢时会用到:microtime(true)。记录开始时刻和结束时刻。
#### 数组、字符串和数据库是我们函数里面最、最、最常用的三类函数。
- 全文搜索:**“那你开始背函数吧”**。
- mb\* 和iconv\* 他们可以处理多字节字符,例如:中文。
中文主要用的是GBK和utf-8两种编码格式。
GBK和utf-8是两个不同的编码委员会对于汉字进行的编码的标准。
- 他们规定**GBK是双字节**,也就是一个汉字占用2Bytes。
- **utf-8是三字节**,一个汉字占用三个字节长度的存储空间。
- >[warning] dump = 倾倒。
- 数组。
~~~
<?php
$shu = array(1 , 1.5 , true ,'天王盖地虎,小鸡炖蘑菇');
echo '<pre>';
var_dump($shu);
echo '</pre>';
?>
~~~
- array(size = 4) 说明里面有4个元素。
0 => int 1 最前的 0 代表的是值的读取标识号,我们称之为下标或者键(英文:key)。
=> 叫作:键值对应符。因此,以后再看到 0=> int 1 可以这样来说。 **下标访问符0 对应 整型的1。**
>[info] 我们还称数组里面的键值对为元素,**元素是键值对的组合(而不只是值)。**
- 索引数组的声明。通过 array() 函数返回数组对象。
所谓索引数组:就是下标全为整型的数组。
键值的增长规则与之前的规则一样。都是最大值加1的原则。
向索引数组中增加元素用: 数组变量名[]、数组变量名[键值]这两种方式来增加元素。
- 使用unset删除变量的方式来删除数组里面的值。
删除了中间的值,并不会让后面的下标向前自动移动。而是原来的值为多少就为多少
删除掉其中的某个值,新加入的值不会替换掉原来的位置,依然遵循最大值加1的原则。
- 索引数组的其他声明方式。
和 TCL 有异曲同工之妙。
~~~
//直接写一个变量后面加上中括号,声明变量
$qi[] = '可口可乐';
$qi[10] ='百事';
~~~或不使用 array() 而直接采用大括号。
- >[success] 还是统一使用 array() 的方式方法。
- 关联数组就是下标可以是字符串的数组。声明和使用方法同上。
- 数组元素的值还是数组,这是多维数组的实现方式。C语言本质也是如此。
- 读取时使用多个\[ \]。
- 数组元素间的分割符为逗号,在数组中插入数组的时候,不要在结尾处写成了分号(;)。
- 遍历二字,从字面解释就是一个接一个全读访问一次,显示出来。
~~~
foreach( 要循环的数组变量 as [键变量 =>] 值变量){
//循环的结构体
}
~~~
- list() 函数:将索引数组下标为0的对应我变量1,下标1的对应变量2,依此类推。
**严格记住**:索引数组的一一对应原则。list第一个变量对应的是下标为0的数组元素,下标为1的对应的是list里面的第二个数组元素。
- each() 函数:读一次向后移动一次【可以想象有一个记录的箭头在移动】,将其中的每个元素拆解成一个新数组。
>[success] 拆解规则详见原书插图。
- 混合使用。遍历的代码量减少,但增加了理解成本。
- 数组操作函数。
array_shift 弹出数组中的第一个元素【shift在键盘上的图标就是一个向上的箭头】
array_unshift 在数组的开始处压入元素
array_push 向数组的末尾处压入元素
array_pop 弹出数组末尾的最后一个元素【就当成是屁从后面出来吧】
current 读出指针当前位置的值
key 读出指针当前位置的键
next 指针向下移
prev 向上移
reset 指针到开始处
end 指针到结束处
- 数组的常用函数
array_combine() 生成一个数组,用一个数组的值作为键名,另一个数组值作为值
range() 创建并返回一个包含指定范围的元素的数组。
compact() 创建一个由参数所带变量组成的数组
array_fill() 用给定的值生成数组
array_chunk() 把一个数组分割为新的数组块
array_merge() 把两个或多个数组合并为一个数组
array_slice() 在数组中根据条件取出一段值,并返回
array_diff() 返回两个数组的差集数组
array_search() 在数组中搜索给定的值,如果成功则返回相应的键名
array_splice() 把数组中的一部分去掉并用其它值取代
array_sum() 计算数组中所有值的和
in_array() 检查数组中是否存在某个值
array_key_exists() 检查给定的键名或索引是否存在于数组中
shuffle() 将数组打乱,保留键值
count() 计算数组中的单元数目或对象中的属性个数
array_flip() 返回一个键值反转后的数组
array_keys() 返回数组所有的键,组成一个数组
array_values() 返回数组中所有值,组成一个数组
array_reverse() 返回一个元素顺序相反的数组
array_count_values() 统计数组中所有的值出现的次数
array_rand() 从数组中随机抽取一个或多个元素,注意是键名
array_unique() 删除重复值,返回剩余数组
sort() 按升序对给定数组的值排序,不保留键名
rsort() 对数组逆向排序,不保留键名
asort() 对数组排序,保持索引关系
arsort() 对数组逆向排序,保持索引关系
ksort() 按键名对数组排序
krsort() 将数组按照键逆向排序
natsort() 用自然顺序算法对数组中的元素排序
natcasesort() 自然排序,不区分大小写
array_filter() 去掉数组中的空元素或者预定元素
extract 将键变为变量名,将值变为变量值
- 世界上最难懂的是道士的鬼符、医生的处方和程序员的正则表达式。
- 定界符//,就是定一个边界,边界以内的就是正则表达式。
- preg_match()。
- \d匹配一个0-9。
\D匹配一个非0-9的值。
\w匹配一个a-zA-Z0-9_。
\W匹配一个非a-zA-Z0-9_。
……
[] 指定范围
- 元字符。
\* 是代表匹配前面的一个原子,匹配0次或者任意多次前面的字符。
\+ 匹配一次或多前前面的一个字符。
? 前面的字符可有可无【可选】 有或没有。
. 更标准一些应该把点算作原子。匹配除了\n以外的所有字符。
|(竖线)或者。注:它的优先级最低了。
^ 必须要以抑扬符之后的字符串开始。
$ 必须要以$之前的字符结尾。
\b 词边界。
\B 非边界。
{m} 有且只能出现m次。
{n,m} 可以出现n到m次。
{m,} 至少m次,最大次数不限制。
() 改变优先级或者将某个字符串视为一个整体,匹配到的数据取出来也可以使用它。
- /正则表达式/模式匹配符
- 把正则的贪婪特性取消掉,让它找到了最近的匹配。
- 正则,**写一点、测一点。**先列出可能情况,TDD。
- 常用正则函数。`P`hp `REG`ular。
preg_filter 执行一个正则表达式搜索和替换
preg_grep 返回匹配模式的数组条目
preg_match 执行一个正则表达式匹配
preg_match_all 执行一个全局正则表达式匹配
preg_replace_callback_array 传入数组,执行一个正则表达式搜索和替换使用回调
preg_replace_callback 执行一个正则表达式搜索并且使用一个回调进行替换
preg_replace 执行一个正则表达式的搜索和替换
preg_split 通过一个正则表达式分隔字符串
- 学习文件处理本质上面就是学习文件处理的函数。
- readfile 读取文件。
file_get_contents 打开文件后,能够赋值给一个变量。
fopen、fread、fclose 操作读取文件。
file_put_contents 写入文件。
fwrite 配合 fopen 进行写入操作。fwrite的别名函数是fputs。
- tmpfile ( )
功能:创建一个临时文件,返回资源类型。关闭文件即被删除。
~~~
<?php
//创建了一个临时文件
$handle = tmpfile();
//向里面写入了数据
$numbytes = fwrite($handle, '写入临时文件');
//关闭临时文件,文件即被删除
fclose($handle);
echo '向临时文件中写入了'.$numbytes . '个字节';
?>
~~~
- 重命名文件。bool rename($旧名,$新名);
复制文件。bool copy(源文件,目标文件);
删除文件。bool unlink(指定路径的文件);
- 文件属性检测函数。
bool file_exists ( $指定文件名或者文件路径)
功能:文件是否**存在**
bool is_readable ( $指定文件名或者文件路径)
功能:文件是否**可读**javascript:;
bool is_writeable ( $指定文件名或者文件路径)
功能:文件是否**可写**
bool is_executable ( $指定文件名或者文件路径)
功能:文件是否**可执行**
bool is_file ( $指定文件名或者文件路径)
功能:是否**是文件**
bool is_dir ( $指定文件名或者文件路径)
功能:是否**是目录**
void clearstatcache ( void )
功能:清楚文件的**状态缓存**
- 文件操作的常量。
平台,分割符。
windows,\。
linux,/。
- 常量:DIRECTORY_SEPARATOR,\_\_FILE\_\_
- 文件指针操作函数。
rewind ( resource handle)
功能:指针回到开始处
fseek ( resource handle, int offset [, int from_where])
功能:文件指针向后移动指定字符
- filesize 检测文件的大小。
file 把整个文件读入一个数组中。
fgets 从文件指针中读取一行,读到最后返回false。
fgetc 从文件指针中读取一个字符,读到最后返回false。
ftruncate 将文件截断到给定的长度。
- filectime 文件创建时间。
filemtime 文件修改时间。
fileatime 文件上次访问时间。
- 文件锁的用途:
若一个人在写入一个文件,另外一个人同时也打个了这个文件进行写入文件。
这情况下,如果遇到一定的碰撞概率的话,不知道到底谁的操作为准。
因此,这个时候我们引入锁机制。
若用户A在写入或者读取这个文件的时候,将文件加上共享锁。我可以读,其他人也可以读。
但是,我如果这与的时候。我使用独占锁。这个文件归我了,你们都别动,除非我将文件锁进行释放。
注意:加上了文件锁后要注意释放。
- bool flock ( resource $handle , int $operation)
LOCK_SH 取得共享锁定(读取的程序)
LOCK_EX 取得独占锁定(写入的程序)
LOCK_UN 释放锁定(无论共享或独占)
- 处理文件夹的基本思想如下:
1. 读取某个路径的时候判断是否是文件夹
2. 是文件夹的话,打开指定文件夹,返回文件目录的资源变量
3. 使用readdir读取一次目录中的文件,目录指针向后偏移一次
4. 使用readdir读取到最后,没有可读的文件返回false
5. 关闭文件目录
- opendir 打开文件夹,返回操作资源
readdir 读取文件夹资源
is_dir 判断是否是文件夹
closedir 关闭文件夹操作资源
filetype 显示是文件夹还是文件,文件显示file,文件夹显示dir
- 文件权限设置
chmod 修改读取模式
chgrp 修改用户组
chown 修改权限
- 文件路径函数
pathinfo 返回文件的各个组成部分
basename 返回文件名
dirname 文件目录部分
parse_url 网址拆解成各部分
http_build_query 生成url 中的query字符串
http_build_url 生成一个url
- ![](https://box.kancloud.cn/document_2015-09-09_55efe05a2efff.png =300x300)
程的项目也许用文件比较好,估计不会有那么大的订户。重复的话,可以进行文本去重。
>[warning] **文件上传的处理步骤:**
> 1. 判断是否有错误码
> 2. 自定义判断是否超出文件大小范围
> 3. 判断后缀名和mime类型是否符合
> 4. 生成文件名
> 5. 判断是否是上传文件
> 6. 移动临时文件到指定位置
- php.ini 的配置项:
file_uploads on为 开启文件上传功能,off为关闭。
post_max_size 系统允许的POST传参的最大值。
upload_max_filesize 系统允许的上传文件的最大值。
memory_limit 内存使用限制。
max_execution_time,上传超时参数的单位为秒。
- 系统返回的错误码详解:
0 无误,可以继续进行文件上传的后续操作。
1 超出上传文件的最大限制,upload_max_filesize = 2M php.ini中设置,一般默认为2M。可根据项目中的实际需要来修改
2 超出了指定的文件大小,根据项目的业务需求指定上传文件的大小限制
3 只有部分文件被上传
4 文件没有被上传
5 (php没有设)
6 找不到临时文件夹,可能目录不存在或没权限
7 文件写入失败,可能磁盘满了或没有权限
- MIME(Multipurpose Internet Mail Extensions)是多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
- 文件上传用的表单。
```
<html>
<head>
<meta charset="utf-8" />
<title>单文件上传</title>
</head>
<body>
<form action="file.php" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
</body>
</html>
```
- PHP为文件类数据准备了一个专用的系统函数$\_FILES,上传文件的所有相关数据,都保存在这个系统函数中。可以var_dump这个$\_FILES ,来观察这个数组的结构。
>'tmp_name' => string 'E:\wamp\tmp\phpC32A.tmp' (length=23)
- 根据这个数组提供的相关信息对文件进行上传后的处理。
- 多个input,每个都是单文件上传 = 多文件上传。
- 从5.4开始,引入session.upload_progress的新特性,我们只需要在php.ini中开启配置,即可通过session监控文件上传进度。
---
- 学习图像处理(GD系统的函数)。需要连带GD库一起来编译 PHP。GD 库和PHP可能需要其他的库,这取决于你要处理的图像格式。
- 用 phpinfo() 查看我们当前的机器是否安装了GD扩展。存在了gd这个选项,就支持。
1.打开php.ini(在文件上传这一章已有说明)
2.在 Windows 中,需要将GD2的DLL文件php_gd2.dll作为一个扩展包含在 php.ini 中。修改;extension = php_gd2.dll,将前面的分号去掉
3.重新启动apache服务器
4.再次执行phpinfo尝试查看是否存在gd扩展
- 用图片处理函数画一张图:
1. 按照机器思维分析步骤。
- [《学完这招,你就可以开始用PPT画画了》](http://www.jianshu.com/p/99f75968e4fa)
2. 分析需要使用到的函数。
- 先把画布准备好: imagecreate()
- 再准备颜料:imagecolorallocate()
3. 按步骤调用函数画图。
- allocate [ˈæləkeɪt]:把…拨给。
- 生成验证码。根据验证码的效果来推理实现的过程。
- 图像缩放和裁剪技术。(略)
图片水印处理。(略)
- 在开发中,显示错误对我们的开发非常有利。因为,显示错误后能帮我们快速定位错误、解决问题。而在**生产环境(即公网)**给其他人访问的的网站、微网站、手机网站、手机接口等,如果错误显示出来了,就容易暴露:
1. 服务器的文件路径和文件存储规范
2. 有些人喜欢用个人名命名,通过社会工程学可以反向推理出密码
3. 有时还会暴露mysql数据库服务器的地址
......
上面这些信息特别容易被网上别有用心的一些人给利用。
- 在 php.ini 中可以控制 php 的错误显示状态:display_errors。
- ini_get() 和 ini_set() 函数。
修改完php.ini文件,需要重启服务器。
- 错误级别。
1. error 最严重,必须要解决。不然程序无法继续向下执行。
2. warning 也很重要。通常也必须要解决。如果明确的,故意的可以不用处理。
3. notice 你可以不用管。但是在有些公司,项目标准特别高。在高标准要求的项目中也必须要解决。因为,notice 会影响到 PHP 的执行效率。通常发生在函数未定义等。
4. parse 错误,是指语法写错了,必须要解决。
5. 代表全部类型的所有错误。
- 错误记录日志。
专门的日志收集系统 vs 通过文件来当服务器的运行日志。
其中:PHP 的错误、警告这些是必须要收集的。
为了不让用户看到,设置好了错误报告级别号,又如何将错误收集到日志系统中呢?
- error_log() 函数可以把错误信息发送到web服务器的错误日志,或者到一个文件里。
>php.ini
log_errors on/off 是否开启日志记录
log_errors_max_len 整型,默认1024 单行错误最大记录长度
error_log syslog或者指定路径 错误日志记录在什么地方
- syslog是指系统来记录。windows系统在电脑的日志收集器里面。linux默认在:/etc/syslog.conf。若Linux系统启动或修改了日志收集。可能存储在第三方专用的日志收集服务器中。
- 自定义错误处理函数。有计划开始要自己写框架时、或者您做完了本书的第一个项目,再回头来看。
- set_error_handler ( callable $回调的错误处理函数)
设置一个用户定义的错误处理函数
trigger_error ( string $error_msg)
产生一个用户级别的 error/warning/notice 信息
---
## MySQL对于PHP程序员来说就是将业务转化成表结构。做好业务中的增、删、改、查。
- 大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。
- 在最开始学习MySQL的时候,并不需要学习MySQL数据库,学到DBA(数据库管理员)的级别。
- [《3天入门MySQL》](http://mysql.phpxy.com/146038)。
- [sqlfiddle.com](http://www.sqlfiddle.com) 在线练习。
- 数据库的五个基本单位
1. 数据库服务器:用来运行数据库服务的一台电脑。
2. 数据库
3. 数据表
4. 数据字段,也叫数据列。
5. 数据行
- 社会工程学中,人们喜欢用相同的密码。因此,用户的密码必须要进行再次加密,不可逆向解密。因为害怕看到了某个用户的密码后,用这个密码去尝试用户的其他银行卡。
- 密码必须使用md5等加密方式帮用户进行加密。用户输入原密码如:123456。我们使用md5将用户输入的123456加密后与数据库的密码进行对比。 一致则密码通过。不一致则用户将密码输入错误了。
- 搜索 mysql **server** 下载。
1. develop 是指服务器为开发机【推荐】
2. server only只安装服务器
3. client only 只安装客户操作端
4. full 全部安装
5. custom 自定义
- Config Type(配置文件类型)
1. Development Machine 是指开发服务器
2. Server Machine 服务器
3. Dedicated Machine 专用服务器仅作为数据库服务器使用
TCP/IP 是指开放的端口:mysql 默认的端口是 3306。
- 设置 **数据库管理系统中 root 用户** 的密码,并非 linux 系统中的 root 用户密码。
- 结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;**同时也是数据库脚本文件的扩展名**。
- SQL语句按照其功能范围不同可分为3个类别:
**`结构`**:操作对象是数据库、数据表、数据字段
- 数据**定义**语言(DDL ,Data Defintion Language)语句:数据定义语句,用于定义不同的数据段、数据库、表、列、索引等。常用的语句关键字包括create、drop、alter等。
**`内容`**:操作对象是记录
- 数据**操作**语言(DML , Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据的完整性。常用的语句关键字主要包括insert、delete、update和select等。
**`权限`**:操作对象是用户
- 数据**控制**语言(DCL, Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。
> 这里作者没写事务操作。
- 如果加入到了windows的环境变量中,可以在命令行下直接操作。
在命令行下,通过以下命可以连接到数据库服务器:
> mysql -h localhost -u root -p
上面的命令中: mysql 表示 mysql数据库启动工具。
-h 表示数据库连接地址,连接本机可不填
-u 表示要登录的用户
-p 表示使用密码登录
注:通常我们不直接输入密码。而是在回车之后,输入密码。
- 每一个命令结束可以输入\g 或者 ;
- 需要帮助的话,通过 `help;` 或者 `\h` 命令来显示帮助内容。
通过 `\c` 命令来清除命令行历史。
- 操作数据库:
```
create database 数据库名;
show databases;
use 库名;
show tables;
drop database 库名;
```
- 操作数据表:
```
create table 表名(字段名1 字段类型, ...., 字段名n 字段类型n);
// int 代表整型。float 代表浮点。char 和 varchar 代表字符串。
// 可以在类型后接上长度。
desc 表名;
show create table 表名 \G;
// 还可以看到表的 engine(存储引擎) 和 charset(字符集)等信息。
// “\G”选项的含义是使得记录能够按照字段竖着排列,
// 对于内容比较长的记录更易于显示。
drop table 表名;
```
- 在创建表最后,我们常用 MyISAM 或者 InnoDB 引擎。
在指定引擎时,我们可以使用:
> ENGINE=InnoDB
指定表默认字符集:
> DEFAULT CHARSET=utf8
效果如下:
> CREATE TABLE emp (
useraname varchar(10) DEFAULT NULL,
password date DEFAULT NULL,
) **ENGINE=InnoDB** **DEFAULT CHARSET=utf8**;
- 操作数据表:
```
alter table 表名 modify 字段名 varchar(20);
// 修改表字段类型 modify。
alter table 表名 add column 字段名 类型;
ALTER TABLE 表名 ADD 字段名 字段类型 AFTER 字段名;
ALTER TABLE 表名 ADD 字段名 字段类型 FIRST;
alter table 表名 drop column 字段名;
alter table 表名 change 字段原名 字段新名 字段类型;
```
字段 增加 和 修改 语句(add/change/modify)中,最后都可以加一个可选项 **first** | **after**。
```
alter table 旧表名 rename 新的表名;
```
- 数据类型。
1. 数值类型(整型、浮点)
2. 字符串类型
3. 日期时间类型
4. 复合类型
5. 空间类型(非科学性工作基本不用,不做讲解)
- 整型。
tinyint 1字节 -128~127
smallint 2字节 -32768~32767
mediumint 3字节 -8388608~8388607
**int 4字节 范围-2147483648~2147483647 // 正负21亿**
bigint 8字节 +-9.22*10的18次方
- 浮点类型。
**float(m, d) 4字节 单精度浮点型,m总个数,d小数位**
double(m, d) 8字节 双精度浮点型,m总个数,d小数位
decimal(m, d) decimal是存储为字符串的浮点数
- 字符类型。
**CHAR 0-255字节 定长字符串**
**VARCHAR 0-255字节 变长字符串**
TINYBLOB 0-255字节 不超过255个字符的二进制字符串
TINYTEXT 0-255字节 短文本字符串
>[info] BLOB 0-65535字节 **二进制形式**的长文本数据
TEXT 0-65535字节 长文本数据
MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
LOGNGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295字节 极大文本数据
VARBINARY(M) 允许长度0-M个字节的定长字节符串 值的长度+1个字节
BINARY(M) M 允许长度0-M个字节的定长字节符串
- CHAR 类型用于定长字符串,并且必须在圆括号内用一个**大小修饰符**来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。VARCHAR 类型把该长度视为最大值并且只使用存储字符串实际需要的长度,类型不会被空格填补,但长于该指示器的值仍然会被截短。
因 VARCHAR 类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间。
- text类型与blob类型。
对于字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小,它们都有不同的子类型。
这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。
BLOB 类型区分大小写(**因为是二进制**),而 TEXT 不区分大小写。
- **大小修饰符**不用于各种 BLOB 和 TEXT 子类型。
- blob = binary large object = 二进制大对象。
- 时间类型。
date 3字节 日期,格式:2014-09-18
time 3字节 时间,格式:08:42:30
datetime 8字节 日期时间,格式:2014-09-18 08:42:30
timestamp 4字节 自动存储记录修改的时间
year 1字节 年份
>[success] 时间类型在web系统中用的比较少,很多时候很多人喜欢**使用int来存储时间。插入时插入的是unix时间戳**,因为这种方式更方便计算。在前端业务中用date类型的函数,再将unix时间戳转成人们可识别的时间。有些人**为了在数据库管理中方便查看,也有人使用datetime类型**来存储时间。
- 复合类型。