PHP进阶篇——学习笔记

类和面向对象

1、在类中定义的变量称之为属性,属性声明是由关键字 public,protected 或者 private 开头,后面跟一个普通的变量声明来组成。

public:公开的
protected:受保护的
private:私有的

protected属性在序列化后会出现不可见字符\00*\00(‘\00’相当于一个ascii码为0的字符),PHP7.1以上版本对属性类型不敏感,public属性序列化不会出现不可见字符
private属性被序列化的时候属性值会变成%00类名%00属性名,根据规则进行修改

2、function:在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法。
注意:同属性一样,类的方法也具有public,protected 以及 private 的访问控制。
3、static:静态方法,静态方法不需要实例化对象,可以通过类名直接调用,操作符为双冒号::。静态属性在定义时在关键字后面加staic即可,在类定义中使用静态成员的时候,用self关键字后面要跟着’::’,而’::'后面则需要跟$符号。

1、可以静态调用,可以动态调用
2、静态属性时不允许对象使用  ->  操作符调用、$this伪变量也不允许使用
3、可以使用self,parent,static在内部调用静态方法与属性。(parent:是当前父类指针;self:是当前类指针)
调用父类静态方法和属性,用patent::$xxx
调用当前类或本类的方法和属性用self::$xxx或者static::$xxx

之后回头看视频,再总结一次

1,静态属性 用于保存 类的公有数据
2,静态方法 里面只能访问 静态属性
3,静态成员 不需要实例化对象 就可以访问
4,类的内部 可以通过self或static关键字访问自身静态成员
5,可以通过parent关键字访问父类的静态成员
6,可以通过类的名称在类定义外部访问静态成员

4、构造函数:PHP5使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用该函数来进行一些初始化工作。
注意:子类中如果定义了__construct则不会调用父类的__construct,想要调用父类函数,需要使用parent::__construct()显式的调用。
析构函数:PHP5支持析构函数,使用__destruct()进行定义,析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。(PHP代码执行完毕以后,会自动回收与销毁对象,所以一般不用!)

5、empty() 函数用于检查一个变量是否为空。
empty() 并不会产生警告,哪怕变量并不存在。 这意味着 empty() 本质上与 !isset($var) || $var == false 等价。
当 var 存在,并且是一个非空非零的值时返回 FALSE 否则返回 TRUE。
以下的变量会被认为是空的:

"" (空字符串)
0 (作为整数的0)
0.0 (作为浮点数的0)
"0" (作为字符串的0)
NULL
FALSE
array() (一个空数组)
$var; (一个声明了,但是没有值的变量)

6、class Truck extends Car:拓展一个Car类。

7、属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。方法的重载通过__call来实现,当调用不存在的方法的时候,将会转为参数调用__call方法,当调用不存在的静态方法时会使用__callStatic重载。

8、__clone:clone方法来复制一个对象,

9、序列化:serialize方法将对象序列化为字符串
反序列化:unserialize将字符串反序列化

函数补充

回调函数

1、array_map()
将函数作用到数组中的每个值上,每个值都乘以本身,并返回带有新值的数组:

<?php
function myfunction($v)
{
  return($v*$v);
}

$a=array(1,2,3,4,5);
print_r(array_map("myfunction",$a));
?>

2、array_walk()、array_walk_recursive()
array_walk() 函数对数组中的每个元素应用用户自定义函数。即对数组中每一个元素都使用一次自定义的方法。

<?php
function myfunction(&$value,$key)
{
$value="yellow";
}
$a=array("a"=>"red","b"=>"green","c"=>"blue");
array_walk($a,"myfunction");
print_r($a);
?>
注意&$value,在变量前面加&字符表示指向变量$value的地址

如需操作更深的数组(一个数组中包含另一个数组),可以使用 array_walk_recursive() 函数。

array_walk_recursive() 函数: 对数组中的每个元素应用 ‘用户自定义函数’。在函数中,数组的键名和键值是参数。该函数与 array_walk() 函数的不同在于可以操作更深的数组(一个数组中包含另一个数组)。

<?php
function myfunction($value,$key)
{
echo "The key $key has the value $value<br>";
}
$a1=array("a"=>"red","b"=>"green");
$a2=array($a1,"1"=>"blue","2"=>"yellow");
array_walk_recursive($a2,"myfunction");
?> 

3、call_user_func()、call_user_func_array()
call_user_func(): 把第一个参数作为回调函数调用,其余参数当作变量传入回调函数中。

function study($username){
	echo $username.' is a good boy';
} 
call_user_func('study','king');
输出结果:king is a good boy

call_user_func_array():调用回调函数,并把一个数组参数作为回调函数的参数。

call_user_func_array('study',array(1,2,3))
传入的参数为数组

匿名函数

5、create_function()用的比较少

自定义函数

require 和 include
require():用于引入模块、 JSON、或本地文件
require_once():语句在脚本执行期间包含并运行指定文件(通俗一点,括号内的文件会执行一遍)。此行为和require()语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含。

通过require、require_once包含文件不存在时会产生一个致命错误和一个警告,程序终止执行

include():
include_once():语句在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。

include、include_once包含不存在文件时会产生两个警告,程序继续执行

PHP include 和 require 语句

通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件(在服务器执行它之前)。

include 和 require 语句是相同的,除了错误处理方面:

require 会生成致命错误(E_COMPILE_ERROR)并停止脚本
include 只生成警告(E_WARNING),并且脚本会继续

因此,如果您希望继续执行,并向用户输出结果,即使包含文件已丢失,那么请使用 include。否则,在框架、CMS 或者复杂的 PHP 应用程序编程中,请始终使用 require 向执行流引用关键文件。这有助于提高应用程序的安全性和完整性,在某个关键文件意外丢失的情况下。

面向对象补充

1、final方法(PHP5)
子类方法中编写与父类方法完全一致的方法名和方法,可以对父类方法进行覆盖,但有的时候我们并不希望父类的方法被覆盖掉。在父类的方法名字前加上final即可。或者说,连子类也不想让它继承,即不允许继承子类,在父类类名前加上final即可。

//对于不想被任何类继承的类可以在class前添加final关键字
final class fatherClass{
	public function test(){
		echo "abc"}
	//对于不想被子类修改(重写)的方法,可以在方法定义的前面加final关键字
	final public function test(){
		echo "abc"}
}
注意:不允许重写的方法依旧可以调用,只是不允许重写

注意:用parent关键字可以访问父类中被子类重写的方法

面向对象编程—对象接口

1、使用interface关键字来定义接口,接口里面的方法不需要有方法的实现。
2、inplements关键字用来表示实现某个接口,实现某个接口之后,必须提供接口中定义的方法的具体实现。
3、可以用instanceof关键字来判断某个对象是否实现了某个接口
4、可以用extends来让接口继承接口,当类实现子接口时,父接口定义的方法也需要在这个类里面具体实现

在这里插入图片描述面向对象-多态:相同的一行代码,对于传入不同的接口的实现的对象的时候,表现的是不同的,这就是多态。

面向对象-抽象类:abstract关键字用来定义抽象类,在抽象方法前 面添加abstract关键字可以表明这个方法是抽象方法不需要具体实现;在抽象类中可以包含普通的方法,有方法的具体实现。继承抽象类的关键字也一样是extends,继承抽象类的子类需要实现抽象类中定义的抽象方法。

魔术方法

为什么要用魔术方法呢?
魔术方法的用处:

举个简单的例子,当类里面没有属性$ name; 但是你不小心访问这个属性,
这个时候就会出错。但是让你可以设置魔术方法__get($ name){ return $ name . "不存在"};就会自动调用__get($name);
这样程序就会不因为你访问了一个不存在的属性报错而中断执行 

1、__tostring和__invoke

__tostring方法会在把对象转换为staring的时候自动调用

__invoke会在把对象当做一个方法调用的时候自动调用

2、__call和__callStatic
(1).魔术方法 __call():当对象访问不存在的方法名称时,此方法会被自动调用。
①调用示例:public function __call($ name,$argument){}

②注意:访问控制关键字必须为public;必须有两个参数:对象访问的方法名称($ name)、方法包含的参数($argument,数组);

(2).魔术方法 __callStatic():当对象访问不存在的静态方法名称时,此方法会被自动调用。

3、__get(),__set(),__isset(),__unset()

*读取不可访问属性的值时,__get()会被调用;
*在给不可访问的属性赋值时,__set()会被调用;
*当对不可访问属性调用isset()或empty()时,__isset()会被调用;
*当对不可访问属性调用unset(),__unset()会被调用。
*所谓不可访问属性,实际上就是在调用某个属性时发现这个属性没有被定义,这时候不同的操纵会触发不同的魔术方法。
*这几个方法也被称为属性重载的魔术方法。

4、__clone():克隆对象的时候自动调用。

正则表达式

1、分隔符
经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)。
分隔符后面可以使用模式修饰(正)符,模式修饰符包括:i, m, s, x等。

例如使用i修饰符可以忽略大小写匹配;

如:"/abc/i"可以与abc或aBC或ABc等匹配;

m 将字符串视为多行,不管是那行都能匹配;

例://模式为:$mode="/abc/m";
//要匹配的字符串为:$str="bcefg5e\nabcdfe"
//注意其中\n,换行了;abc换到了下一行;
//$str和$mode仍可以匹配,修正符m使得多行也可匹配;

s 将字符串视为单行,换行符作为普通字符;

例://模式为:$mode="/pr.y/";
//要匹配字符串为:$str="pr\ny";
//两者不可匹配; . 是除了换行以外的字符可匹配;
//修改下模式为:$mode="/pr.y/s";
//其中修正符s将\n视为普通字符,即不是换行;
//最后两者可以匹配;

x 将模式中的空白忽略;
A 强制从目标字符串开头匹配;

例://$mode="/abc/A";
//可以与$str="abcsdfi"匹配,
//不可以与$str2="sdsdabc"匹配;
//因为$str2不是以abc开头;

g表示全局匹配;

g 全局(global)匹配 
如果不带g,正则过程中字符串从左到右匹配,找到第一个符合条件的即匹配成功,返回
如果带g,则字符串从左到右,找到每个符合条件的都记录下来,知道字符串结尾位置
例如: 
var str = 'aaaaaaaa'
var reg1 = /a/;  str.match(reg1)  // 结果为:["a", index: 0, input: "aaaaaaaa"]
var reg2 = /a/g; str.match(reg2)  // 结果为:["a", "a", "a", "a", "a", "a", "a", "a"]

D 如果使用$限制结尾字符,则不允许结尾有换行;

例://模式为:$mode="/abc$/";
//可以与最后有换行的$str="adshabc\n"匹配;
//元子符$会忽略最后的换行\n;
//如果模式为:$mode="/abc/D",
//则不能与$str="adshabc\n"匹配,

U 只匹配最近的一个字符串;不重复匹配;

例:
如模式为:
$mode="/a.*c/";
$str="abcabbbcabbbbbc" ;
preg_match($mode,$str,$content);
echo $content[0]; //输出:abcabbbcabbbbbc;

//如果$mode="/a.*c/";变成$mode="/a.*c/U";
// 则只匹配最近一个字符串,输出:abc;

如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。
\b是正则表达式规定的一个特殊代码,代表着单词的开头或结尾。虽然通常英文的单词是由空格或标点符号或换行为分隔的,但是\b并不代表这些单词分隔符中的任何一个,只代表一个位置。

假如你要找的是hi后面不远处跟着一个Lucy,你应该用\bhi\b.*\bLucy\b。

修正符:e 配合函数preg_replace()使用,
可以把匹配来的字符串当作正则表达式执行;

2、$ p=“http://”,preg_quote($ p, ‘/’)其实就是把$p中的所有的"/"转义一下,不然你要自己写,太多了的话麻烦。前后的’/’,’/'就是正则的分隔符。

3、元字符与转义
(1)元字符

元字符具有两种使用场景,一种是可以在任何地方都能使用,另一种是只能在方括号内使用。
在方括号内的使用方法:

\ 转义字符
^ 仅在作为第一个字符(方括号内)时,表明字符类取反
- 标记字符范围

(2) 贪婪模式与懒惰模式

正则表达式中每个元字符匹配一个字符,当使用+之后将会变的贪婪,它将匹配尽可能多的字符,但使用问号?字符时,它将尽可能少的匹配字符,既是懒惰模式。

贪婪模式:在可匹配与可不匹配的时候,优先匹配

//下面的\d表示匹配数字
$p = '/\d+\-\d+/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //结果为:010-12345678

懒惰模式:在可匹配与可不匹配的时候,优先不匹配

$p = '/\d?\-\d?/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0];  //结果为:0-1

当我们确切的知道所匹配的字符长度的时候,可以使用{}指定匹配字符数

$p = '/\d{3}\-\d{8}/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //结果为:010-12345678

(提示:\w匹配字母或数字或下划线,\s匹配任意的空白符,包括空格、制表符、换行符)
preg_match只能匹配一次结果,但很多时候我们需要匹配所有的结果,preg_match_all可以循环获取一个列表的匹配结果数组。

做题目时碰到顺便补充一下

1、preg_match()

preg_match (要搜索的模式,字符串,参数)
   在字符串里搜索符合 ‘要搜索的模式’ 的字符,并返回给参数。

2 、trim()
trim(字符串,字符) 移除字符串两侧的空白字符或其他预定义字符。举个栗子:

<?php
$str = "Hello World!";
echo $str . "<br>";
echo trim($str,"Hed!");
?>
执行结果:
Hello World!
llo Worl

正则表达式

表达式说明
.匹配除 “\n” 之外的任何单个字符
*匹配它前面的表达式0次或多次,等价于{0,}
+量词,1 次或多次匹配
?作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性
{4,7}最少匹配 4 次且最多匹配 7 次
[:punct:]匹配任何标点符号
\ /匹配 / ,这里的 \ 是为了转义
[^>]表示不是以>开头的任意字符
[a-z]匹配所有小写字母
[A-Z]匹配所有大写字母
^断言目标的开始位置(或在多行模式下是行首)
$断言目标的结束位置(或在多行模式下是行尾)
[开始字符类定义
]结束字符类定义
|开始一个可选分支
(子组的开始标记
)子组的结束标记
{自定义量词开始标记
}自定义量词结束标记
补充说明
特殊代码

特殊代码^ 以及$ 和\b有点类似,都匹配一个位置。^匹配你要用来查找的字符串的开头,$ 匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^ \d{5,12} $。

这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}代表只能不多不少重复2次,{5,12}则是必须重复最少5次,最多12次,否则都不匹配。

因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。

和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配行的开始处和结束处。

字符转义

如果你想查找特殊代码本身的话,比如你查找.,或者*,就出现了问题:你没法指定它们,因为它们会被解释成其它的意思。这时你就必须使用\来取消这些字符的特殊意义。因此,你应该使用.和*。当然,要查找\本身,你也得用\.

例如:deerchao.cn匹配deerchao.cn,c:\windows匹配c:\windows,2^8匹配2^8(通常这是2的8次方的书写方式)。

重复

你已经看过了前面的*,+,{2},{5,12}这几个代表重复的方式了。下面是正则表达式中所有指定重复的方式:
.常用的量词

代码/语法说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

下面是一些使用重复的例子:

Windows\d+:匹配Windows后面跟1个或更多数字

13\d{9}:匹配以13后面跟9个数字(中国的手机号)

^\w+:匹配一行的第一个单词(或整个字符串的第一个单词,具体代表哪个意思得看选项设置)

以上正则表达式内容参考下面大佬的文章,有兴趣可以去看看
https://deerchao.cn/tutorials/regex/regex-1.htm

(3)$matches

$p = '/name:([\w+\s]+)/';
$str = "name:steven jobs";
preg_match($p, $str, $match);
echo $match[1]; //结果为:steven jobs

$match[x]中的x是匹配正则表达式中的子组的位置,0代表全部,1代表第一个子组,2代表第二个子组,以此类推。
子组:子组通过圆括号()界定,意思就是,有一对圆括号,就有一个子组,按前后顺序来排序1,2,3…

[^>]:表示不是以>开头的任意字符。

cookie

1、PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,常用到的前5个:

name( Cookie名)可以通过$_COOKIE['name'] 进行访问
value(Cookie的值)
expire(过期时间)Unix时间戳格式,默认为0,表示浏览器关闭即失效
path(有效路径)如果路径设置为'/',则整个网站都有效
domain(有效域)默认整个域名都有效,如果设置了'www.imooc.com',则只在www子域中有效

在PHP中删除cookie也是采用setcookie函数来实现。setrawcookie跟setcookie基本一样,唯一的不同就是value值不会自动的进行urlencode,因此在需要的时候要手动的进行urlencode。(编码)

setcookie('test', '', time()-1); 
可以看到将cookie的过期时间设置到当前时间之前,则该cookie会自动失效,
也就达到了删除cookie的目的。之所以这么设计是因为cookie是通过HTTP的
标头来传递的,客户端根据服务端返回的Set-Cookie段来进行cookie的设置
,如果删除cookie需要使用新的Del-Cookie来实现,则HTTP头就会变得复杂
,实际上仅通过Set-Cookie就可以简单明了的实现Cookie的设置、更新与删除。

也可以直接通过header来删除cookie。

header("Set-Cookie:test=1393832059; 
expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1));
这里用到了gmdate,用来生成格林威治标准时间,以便排除时差的影响。

cookie中的路径用来控制设置的cookie在哪个路径下有效,默认为’/’,在所有路径下都有,当设定了其他路径之后,则只在设定的路径以及子路径下有效,例如:

setcookie('test', time(), 0, '/path');

上面的设置会使test在/path以及子路径/path/abc下都有效,但是在根目录下就读取不到test的cookie值。

2、session与cookie的异同

cookiesession
cookie将数据存储在客户端,相对不是太安全,容易被盗用导致cookie欺骗单个cookie的值最大只能存储4k每次请求都要进行网络传输,占用带宽session是将用户的会话数据存储在服务端,没有大小限制,通过一个session_id进行用户识别,PHP默认情况下session id是通过cookie来保存的,因此从某种程度上来说,seesion依赖于cookie。但这不是绝对的,session id也可以通过参数来实现,只要能将session id传递到服务端进行识别的机制都可以使用session。

3、删除与销毁session
删除某个session值可以使用PHP的unset函数,删除后就会从全局变量$ _SESSION中去除,无法访问。
如果要删除所有的session,可以使用session_destroy函数销毁当前session,session_destroy会删除所有数据,但是session_id仍然存在。session_destroy并不会立即的销毁全局变量$ _SESSION中的值,只有当下次再访问的时候,$ _SESSION才为空,因此如果需要立即销毁$_SESSION,可以使用unset函数。

PHP文件系统之读取文件内容

(1)file_get_contents:最简单的文件读取函数,可以将整个文件读取的一个字符串中;也可以通过参数控制读取内容的开始点以及长度。

$content = file_get_contents('./test.txt');
$content = file_get_contents('./test.txt', null, null, 100, 500);

(2)类似于C语言操作文件的方法,使用fopen,fgets,fread等方法,fgets可以从文件指针中读取一行,freads可以读取指定长度的字符串。

$ fp = fopen('./text.txt', 'rb');
while(!feof($ fp)) {
    echo fgets($ fp); //读取一行
}
fclose($fp);

注意:用fopen打开的函数,最好要用fclose函数来关闭文件指针,避免文件句柄被占用。

判断文件是否存在函数:is_file与file_exists

(1)file_exists不仅可以判断文件是否存在,同时也可以判断目录是否存在,从函数名可以看出,is_file是确切的判断给定的路径是否是一个文件。

$filename = './test.txt';
if (is_file($filename)) {
    echo file_get_contents($filename);
}

(2)在判断文件是否存在的基础上,可以使用is_readable与is_writeable函数来进一步判断文件是否可读可写。

$filename = './test.txt';
if (is_writeable($filename)) {
    file_put_contents($filename, 'test');
}
if (is_readable($filename)) {
    echo file_get_contents($filename);
}

(3)文件有很多元属性,包括:文件的所有者、创建时间、修改时间、最后的访问时间等。

fileowner:获得文件的所有者
filectime:获取文件的创建时间
filemtime:获取文件的修改时间
fileatime:获取文件的访问时间

其中用到最多的是修改时间,通过文件的修改时间,可以判断文件的时效性,经常用在静态文件或者缓存数据的更新。
(4)filesize函数:可以取得文件的大小

$filename = '/data/webroot/usercode/resource/test.txt';
$size = filesize($filename);

PHP文件系统之写入内容到文件

(1)采用file_put_contents函数。

$filename = './test.txt';
$data = 'test';
file_put_contents($filename, $data);

这样就是一个简单的文件写入的过程啦,把data的内容写入到filename中。
当$ data是数组的时候,会自动的将数组连接起来,相当于$data=implode(’’, $data);
同样的,PHP也支持类似C语言风格的操作方式,采用fwrite进行文件写入。

$fp = fopen('./test.txt', 'w');
fwrite($fp, 'hello');
fwrite($fp, 'world');
fclose($fp);

(2)unlink函数:用来删除文件

unlink($filename);

删除文件夹使用rmdir函数,文件夹必须为空,如果不为空或者没有权限则会提示失败。

rmdir($dir);

如果文件夹中存在文件,可以先循环删除目录中的所有文件,然后再删除该目录,循环删除可以使用glob函数遍历所有文件。

foreach (glob("*") as $filename) {
   unlink($filename);
}

PHP异常处理

1、PHP代码中的异常通过throw抛出,异常抛出之后,后面的代码将不会再被执行。为什么还需要使用异常处理?原因就是

异常抛出被用于在遇到未知错误,或者不符合预先设定的条件时,通知客户程序,
以便进行其他相关处理,不至于使程序直接报错中断。

当代码中使用了try catch的时候,抛出的异常会在catch中捕获,否则会直接中断。

基本语法
    try{
        //可能出现错误或异常的代码
        //catch表示捕获,Exception是php已定义好的异常类
    } catch(Exception $e){
        //对异常处理,方法:
            //1、自己处理
            //2、不处理,将其再次抛出
    }

Exception - 是php已定义好的异常类,具有几个基本属性与方法:
message 异常消息内容
code 异常代码
file 抛出异常的文件名
line 抛出异常在该文件的行数

其中常用的方法有:

getTrace 获取异常追踪信息
getTraceAsString 获取异常追踪信息的字符串
getMessage 获取出错信息

如果必要的话,可以通过继承Exception类来建立自定义的异常处理类。
Try - 使用异常的函数应该位于 “try” 代码块内。如果没有触发异常,则代码将照常继续执行。如果异常被触发,会抛出一个异常。
Throw - 这里规定如何触发异常。注意:每一个 “throw” 必须对应至少一个 “catch”,当然可以对应多个"catch"
Catch - “catch” 代码块会捕获异常,并创建一个包含异常信息的对象。

try{
 checkNum(2);
 //如果异常被抛出,那么下面一行代码将不会被输出
 echo '如果能看到这个提示,说明你的数字小于等于1';
}catch(Exception $e){
 //捕获异常
 echo '捕获异常: ' .$e->getMessage();
}

checkNum()函数:用来检测数字是否大于 1,如果是,则抛出一个异常。

PHP数据库操作

1、连接数据库
PHP连接mysql数据库的方法:(其它数据库连接方法大同小异)

使用mysql_connect函数进行数据库连接,该函数需要指定数据库的地址,用户名及密码。
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

PHP连接数据库的方式类似于直接在命令行下通过进行连接,类似:mysql -hlocalhost -ucode1 -p,当连接成功以后,我们需要选择一个操作的数据库,通过mysql_select_db函数来选择数据库。

mysql_select_db('code1');

通常我们会先设置一下当前连接使用的字符编码,一般的我们会使用utf8编码。

mysql_query("set names 'utf8'");

这样,我们就与数据库建立了连接,可以进行数据操作了。
下面放一个连接的具体命令:

$host = '127.0.0.1';//数据库地址
$user = 'code1';//用户名
$pass = '';//密码
$link = mysql_connect($host, $user, $pass);
mysql_select_db('code1');
mysql_query("set names 'utf8'");

2、利用连接好的数据库进行查询数据
采用mysql_query加sql语句的形式向数据库发送查询指令。

$res = mysql_query('select * from user limit 1');

若数据库存在多连接的情况,则可以通过参数指令从那个连接中进行查询。

$link1 = mysql_connect('127.0.0.1', 'code1', '');
$link2 = mysql_connect('127.0.0.1', 'code1', '', true); //开启一个新的连接
$res = mysql_query('select * from user limit 1', $link1); //从第一个连接中查询数据

3、利用连接好的数据库进行插入数据

$sql = "insert into user(name, age, class) values('李四', 18, '高三一班')";
mysql_query($sql); //执行插入语句

通常数据都是存储在变量或者数组中,因此sql语句需要先进行字符串拼接得到。

$name = '李四';
$age = 18;
$class = '高三一班';
$sql = "insert into user(name, age, class) values('$name', '$age', '$class')";
mysql_query($sql); //执行插入语句

执行插入语句以后,可以得到自增的主键id,通过PHP的mysql_insert_id函数可以获取该id。

$uid = mysql_insert_id();

这个id的作用非常大,通常可以用来判断是否插入成功,或者作为关联ID进行其他的数据操作。

4、PHP数据库操作之取得数据查询结果
PHP有多个函数可以获取数据集中的一行数据,最常用的是mysql_fetch_array,可以通过设定参数来更改行数据的下标,默认的会包含数字索引的下标以及字段名的关联索引下标。

也可以通过设定参数MYSQL_NUM只获取数字索引数组,等同于mysql_fetch_row函数,如果设定参数为MYSQL_ASSOC则只获取关联索引数组,等同于mysql_fetch_assoc函数。

$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM);
 //这两个方法获取的数据是一样的

mysql_fetch_array() 函数:从结果集中取得一行作为关联数组,或数字数组,或二者兼有。
返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。

mysql_fetch_row() :从和结果标识 data 关联的结果集中取得一行数据并作为数组返回。每个结果的列储存在一个数组的单元中,偏移量从 0 开始。
依次调用 mysql_fetch_row() 将返回结果集中的下一行,如果没有更多行则返回 FALSE。

5、PHP数据库操作之查询分页数据

通过mysql的limit可以很容易的实现分页,limit m,n表示从m行后取n行数据,在PHP中我们需要构造m与n来实现获取某一页的所有数据。
假定当前页为 p a g e , 每 页 显 示 page,每页显示 pagen条数据,那么m为当前页前面所有的数据,既$ m = ($page-1) * $n。

$page = 2;
$n = 2;
$m = ($page - 1) * $n;
$sql = "select * from user limit $m, $n";
$result = mysql_query($sql);
//循环获取当前页的数据
$data = array();
while ($row = mysql_fetch_assoc($result)) {
    $data[] = $row;
}

6、 PHP数据库操作之更新与删除数据

数据的更新与删除相对比较简单,只需要构建好相应的sql语句,然后调用mysql_query执行就能完成相应的更新与删除操作。

$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
    echo '更新成功';
}
同样的删除可以使用类似以下的代码:
$sql = "delete from user where id=2 limit 1";
if (mysql_query($sql)) {
    echo '删除成功';
}

7、PHP数据库操作之关闭MySQL连接
当数据库操作完成以后,可以使用mysql_close关闭数据库连接,默认的,当PHP执行完毕以后,会自动的关闭数据库连接。

mysql_close();

但是在对性能要求比较高的情况下,可以在进行完数据库操作之后尽快关闭数据库连接,以节省资源,提高性能。
在存在多个数据库连接的情况下,可以设定连接资源参数来关闭指定的数据库连接。

$link = mysql_connect($host, $user, $pass);
mysql_close($link);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值