PHP
PHP是一种创建动态交互性站点的服务器端脚本语言
PHP能够生成动态页面内容
PHP能够创建、打开、读取、写入、删除以及关闭服务器上的文件
PHP能够接收表单数据
PHP能够发送并取回cookies
PHP能够添加、删除、修改数据库中的数据
PHP能够限制用户访问网站中的某些页面
......
php数组
PHP有两种数组:索引数组、关联数组。
索引和关联两个词都是针对数组的键而言的。
先介绍下索引数组,索引数组是指数组的键是整数的数组,并且键的整数顺序是从0开始,依次类推。
$fruit = array("苹果","香蕉","菠萝"); 注意数组的键是从0开始的。可以使用
print_r($fruit);语句输出数组键及对应的值。
注1:
数组初始化丧三种式:1. $fruit=array(); $fruit[0]='香蕉';
2.$fruit=array("xiangjiao"); 3. $fruit=array('0'=>'xiangjiao');
注2:
echo仅能输出字符串,对于其他变量无能为力。而print_r则是把一个变量的所有人类可阅读的信息输出。
例如:print_r可以以数组为输入,而输出的是人能看懂的数组结构:
$arr = array("1"=>"arr1", "2"=>"arr2", "3"=>"arr3", "4"=>array("4a","4b"));
print_r($arr);
输出结果为:
Array ( [1] => arr1 [2] => arr2 [3] => arr3 [4] => Array ( [0] => 4a [1] => 4b ) )
索引数组赋值有三种方式:
1.array[0]='苹果';
2.$arr=array('0'=>'苹果');
3.$arr=array('苹果');
$fruit = array('苹果','香蕉');
$fruit0 = $fruit['0'];
print_r($fruit0);//结果为苹果
$fruit=array('苹果','香蕉','菠萝');
for($i=0; $i<3; $i++){
echo '<br>数组第'.$i.'值是:'.$fruit[$i];
}
注:echo "数组中的第个{$i}值为$fruit[$i]"."<br>";//这种情况下,必须给变量加大括号!!!!!
双引号里用变量 规范的写法是加上 {} 或者用 . 来连接。
不加{}的话 可以解析 但是
$bao = "zbx"
echo "我的$bao"; 可以正常输出
echo "我的$bao嘿嘿"; 报错 是因为 不加{}的话 他把“$bao嘿嘿”当做一个整体解析成变量了
echo "我的$bao 嘿嘿"; 加个空格就可以出来了
$fruit=array('苹果','香蕉','菠萝');
foreach($fruit as $k=>$v){
echo '<br>第'.$k.'值是:'.$v;
}
关联数组是指数组的键是字符串的数组。
$fruit = array(
'apple'=>"苹果",
'banana'=>"香蕉",
'pineapple'=>"菠萝"
);
可以使用print_r($fruit);语句输出数组键及对应的值。
<?php
//请创建一个数组变量arr,并尝试创建一个关联数组,键是apple,值是苹果
//方法一:
$arr = array();
$arr['apple'] = "苹果";
//方法二:$arr = array('apple'=>"苹果");
if( isset($arr) ) {print_r($arr);}
?>
注:isset()检测变量是否设置 返回boolean
用数组变量的名字后跟中括号+键的方式来访问数组中的值,键使用单引号或者双引号括起来。
$fruit = array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");
$fruit0 = $fruit['banana'];
print_r($fruit0);
foreach循环可以将数组里的所有值都访问到:
$fruit=array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");
foreach($fruit as $k=>$v){
echo '<br>水果的英文键名:'.$k.',对应的值是:'.$v;
}
类与面向对象
类是面向对象程序设计的基本概念,通俗的理解类就是对现实中某一个种类的东西的抽象, 比如汽车可以
抽象为一个类,汽车拥有名字、轮胎、速度、重量等属性,可以有换挡、前进、后退等操作方法。
通常定义一个汽车类的方法为:
class Car {
$name = '汽车';
function getName() {
return $this->name;
}
}
类是一类东西的结构描述,而对象则是一类东西的一个具体实例,例如汽车这个名词可以理解为汽车的
总类,但这辆汽车则是一个具体的汽车对象。
对象通过new关键字进行实例化:
$car = new Car();
echo $car->getName();
类与对象看起来比较相似,但实际上有本质的区别,类是抽象的概念,对象是具体的实例。类可以使程序
具有可重用性。
例:
<?php
//定义一个类
class Car {
var $name = '汽车';
function getName() {
return $this->name;
}
}
//实例化一个car对象
$car = new Car();
$car->name = '奥迪A6'; //设置对象的属性值
echo $car->getName(); //调用对象的方法 输出对象的名字
输出:奥迪A6
<?php
//定义一个Car类并实例化一个对象
class Car{
public $name ='汽车';
public function run(){
echo '我跑~~~<br />';
}
}
//实例化一个对象
$objcar = new Car();
//调用该对象的属性
echo $objcar->name;
//调用该对象的方法
echo $objcar->run();
1. 在类中定义的变量称之为属性,通常属性跟数据库中的字段有一定的关联,因此也可以称作“字段”。
属性声明是由关键字 public,protected 或者 private 开头,后面跟一个普通的变量声明来组成。
属性的变量可以设置初始化的默认值,默认值必须是常量。
2. 默认都为public,外部可以访问。一般通过->对象操作符来访问对象的属性或者方法,对于静态属性
则使用::双冒号进行访问。当在类成员方法内部调用的时候,可以使用$this伪变量调用当前对象的属性。
class Car {
//定义公共属性
public $name = '汽车';
//定义受保护的属性
protected $corlor = '白色';
//定义私有属性
private $price = '100000';
}
$car = new Car();
echo $car->name; //调用对象的属性
echo $car->color; //错误 受保护的属性不允许外部调用
echo $car->price; //错误 私有属性不允许外部调用
受保护的属性与私有属性不允许外部调用,在类的成员方法内部是可以调用的:
class Car{
private $price = '1000';
public function getPrice() {
return $this->price; //内部访问私有属性
}
}
注:带有 $ 符号的字段被认为是变量,而实例化后的对象认为是一个变量所以使用 $object 这种形式,
而属性在类中可以看做是一个变量,所以属性在类中定义的时候需要加上 $ 符,而在对象中,属性是对象
的一部分,所以使用 $object->value 这种形式区分。
方法就是在类中的function,很多时候我们分不清方法与函数有什么差别,在面向过程的程序设计中
function叫做函数,在面向对象中function则被称之为方法。
同属性一样,类的方法也具有public,protected 以及 private 的访问控制。
访问控制的关键字代表的意义为:
public:公开的
protected:受保护的
private:私有的
我们可以这样定义方法:
class Car {
public function getName() {
return '汽车';
}
}
$car = new Car();
echo $car->getName();
使用关键字static修饰的,称之为静态方法,静态方法不需要实例化对象,可以通过类名直接调用,
操作符为双冒号::。
class Car {
public static function getName() {
return '汽车';
}
}
echo Car::getName(); //结果为“汽车”
PHP5可以在类中使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用
该函数,因此常用来在对象创建的时候进行一些初始化工作。
class Car {
function __construct() {
print "构造函数被调用\n";
}
}
$car = new Car(); //实例化的时候 会自动调用构造函数__construct,这里会输出一个字符串
在子类中如果定义了__construct则不会调用父类的__construct,如果需要同时调用父类的构造函数,
需要使用parent::__construct()显式的调用。
class Car {
function __construct() {
print "父类构造函数被调用\n";
}
}
class Truck extends Car {
function __construct() {
print "子类构造函数被调用\n";
parent::__construct();
}
}
$car = new Truck();
同样,PHP5支持析构函数,使用__destruct()进行定义,析构函数指的是当某个对象的所有引用被删除,
或者对象被显式的销毁时会执行的函数。
class Car {
function __construct() {
print "构造函数被调用 \n";
}
function __destruct() {
print "析构函数被调用 \n";
}
}
$car = new Car(); //实例化时会调用构造函数
echo '使用后,准备销毁car对象 \n';
unset($car); //销毁时会调用析构函数
当PHP代码执行完毕以后,会自动回收与销毁对象,因此一般情况下不需要显式的去销毁对象。
注:构造函数就是:你生下来就开始执行(长头发,张牙齿,吃饭,玩)
析构函数就是:你香消玉殒的时候就会执行(放进棺材,埋进土里)
静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用。静态属性不允许
对象使用->操作符调用。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
}
echo Car::getSpeed(); //调用静态方法
静态方法也可以通过变量来进行动态调用
$func = 'getSpeed';
$className = 'Car';
echo $className::$func(); //动态调用静态方法
静态方法中,$this伪变量不允许使用。可以使用self,parent,static在内部调用静态方法与属性。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
public static function speedUp() {
return self::$speed+=10;
}
}
class BigCar extends Car {
public static function start() {
parent::speedUp();
}
}
BigCar::start();
echo BigCar::getSpeed();
注:无论是"->"还是"::",可以理解为"的"。
this :当前对象的指针
self:当前类的指针,调用静态方法时
parent:当前父类的指针,调用静态方法时
访问控制通过关键字public,protected和private来实现。被定义为公有的类成员可以在任何地方被访问。
被定义为受保护的类成员则可以被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所
在的类访问。
类属性必须定义为公有、受保护、私有之一。为兼容PHP5以前的版本,如果采用 var 定义,则被视为公有。
class Car {
$speed = 10; //错误 属性必须定义访问控制
public $name; //定义共有属性
}
类中的方法可以被定义为公有、私有或受保护。如果没有设置这些关键字,则该方法默认为公有。
class Car {
//默认为共有方法
function turnLeft() {
}
}
如果构造函数定义成了私有方法,则不允许直接实例化对象了,这时候一般通过静态方法进行实例化,在设
计模式中会经常使用这样的方法来控制对象的创建,比如单例模式只允许有一个全局唯一的对象。
class Car {
private function __construct() {
echo 'object create';
}
private static $_object = null;
public static function getInstance() {
if (empty(self::$_object)) {
self::$_object = new Car(); //内部方法可以调用私有方法,因此这里可以创建对象
}
return self::$_object;
}
}
//$car = new Car(); //这里不允许直接实例化对象
$car = Car::getInstance(); //通过静态方法来获得一个实例
继承是面向对象程序设计中常用的一个特性,汽车是一个比较大的类,我们也可以称之为基类,除此之外,
汽车还分为卡车、轿车、东风、宝马等,因为这些子类具有很多相同的属性和方法,可以采用继承汽车类
来共享这些属性与方法,实现代码的复用。
例:
<?php
class Car {
public $speed = 0; //汽车的起始速度是0
public function speedUp() {
$this->speed += 10;
return $this->speed;
}
}
//定义继承于Car的Truck类
class Truck extends Car {
public function speedUp() {
parent::speedUp();
$this->speed +=50;
return $this->speed;
}
}
$car = new Truck();
$car->speedUp();
echo $car->speed;//输出60
PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的。属性的重载通过__set,__get,
__isset,__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。
class Car {
private $ary = array();
public function __set($key, $val) {
$this->ary[$key] = $val;
}
public function __get($key) {
if (isset($this->ary[$key])) {
return $this->ary[$key];
}
return null;
}
public function __isset($key) {
if (isset($this->ary[$key])) {
return true;
}
return false;
}
public function __unset($key) {
unset($this->ary[$key]);
}
}
$car = new Car();
$car->name = '汽车'; //name属性动态创建并赋值
echo $car->name;
方法的重载通过__call来实现,当调用不存在的方法的时候,将会转为参数调用__call方法,当调用不存在
的静态方法时会使用__callStatic重载。
class Car {
public $speed = 0;
public function __call($name, $args) {
if ($name == 'speedUp') {
$this->speed += 10;
}
}
}
$car = new Car();
$car->speedUp(); //调用不存在的方法会使用重载
echo $car->speed;
注:这里的重载不是c++或者java意义上的重载,而是php的一个默认函数__call($name,$args),
当你要调用的函数不存在时,函数名(speedDown)传给形参$name,里面的参数传给形参$args,
然而内部具体执行需要自己编写。
对象比较,当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,当需要判断
两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断。
通过$obj2 = clone $obj1;可以将$obj1中的所有属性都克隆给$obj2,使得两者的属性值都相同,
使用$obj2 == $obj1 判断得true,但他们并不指向同一块内存空间,所以$obj1 === $obj2 判断
为false。
通过$obj2 = $obj1;可以使得$obj2和$obj1都指向同一块内存空间,所以$obj1 == $obj2
和$obj1 === $obj2 判断都为true。
对象复制,在一些特殊情况下,可以通过关键字clone来复制一个对象,这时__clone方法会被调用,
通过这个魔术方法来设置属性的值。
class Car {
public $name = 'car';
public function __clone() {
$obj = new Car();
$obj->name = $this->name;
}
}
$a = new Car();
$a->name = 'new car';
$b = clone $a;
var_dump($b);
对象序列化,可以通过serialize方法将对象序列化为字符串,用于存储或者传递数据,然后在需要的时候
通过unserialize将字符串反序列化成对象进行使用。
class Car {
public $name = 'car';
}
$a = new Car();
$str = serialize($a); //对象序列化成字符串
echo $str.'<br>';
$b = unserialize($str); //反序列化为对象
var_dump($b);
正则表达式
正则表达式是对字符串进行操作的一种逻辑公式,就是用一些特定的字符组合成一个规则字符串,称之
为正则匹配模式。
$p = '/apple/';
$str = "apple banna";
if (preg_match($p, $str)) {
echo 'matched';
}
其中字符串'/apple/'就是一个正则表达式,他用来匹配源字符串中是否存在apple字符串。
PHP中使用PCRE库函数进行正则匹配,比如上例中的preg_match用于执行一个正则匹配,常用来判断一类
字符模式是否存在。
PCRE库函数中,正则匹配模式使用分隔符与元字符组成,分隔符可以是非数字、非反斜线、非空格的
任意字符。经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~),例如:
/foo bar/
#^[^0-9]$#
~php~
如果模式中包含分隔符,则分隔符需要使用反斜杠(\)进行转义。
/http:\/\//
如果模式中包含较多的分割字符,建议更换其他的字符作为分隔符,也可以采用preg_quote进行转义。
$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;
分隔符后面可以使用模式修饰符,模式修饰符包括:i, m, s, x等,例如使用i修饰符可以忽略大小写匹配:
$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
echo '匹配成功';
}
注:
正则表达式中常用的模式修正符有i、g、m、s、x、e等。它们之间可以组合搭配使用。
它们的作用如下:
i | 不区分大小写
g | 全局匹配
m | 将字符串视为多行,不管是那行都能匹配
s | 将字符串视为单行,换行符作为普通字符
x | 将模式中的空白忽略
A | 强制从目标字符串开头匹配
D | 如果使用$限制结尾字符,则不允许结尾有换行
U | 只匹配最近的一个字符串,不重复匹配
e | 配合函数preg_replace()使用,可以把匹配来的字符串当作正则表达式执行
正则表达式中具有特殊含义的字符称之为元字符,常用的元字符有:
\ 一般用于转义字符
^ 断言目标的开始位置(或在多行模式下是行首)
$ 断言目标的结束位置(或在多行模式下是行尾)
. 匹配除换行符外的任何字符(默认)
[ 开始字符类定义
] 结束字符类定义
| 开始一个可选分支
( 子组的开始标记
) 子组的结束标记
? 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词)
* 量词,0 次或多次匹配
+ 量词,1 次或多次匹配
{ 自定义量词开始标记
} 自定义量词结束标记
//下面的\s匹配任意的空白符,包括空格,制表符,换行符。[^\s]代表非空白符。[^\s]+表示一次或多次
匹配非空白符。
$p = '/^我[^\s]+(苹果|香蕉)$/';
$str = "我喜欢吃苹果";
if (preg_match($p, $str)) {
echo '匹配成功';
}
元字符具有两种使用场景,一种是可以在任何地方都能使用,另一种是只能在方括号内使用,在方括号内
使用的有:
\ 转义字符
^ 仅在作为第一个字符(方括号内)时,表明字符类取反
- 标记字符范围
其中^在反括号外面,表示断言目标的开始位置,但在方括号内部则代表字符类取反,方括号内的减号-可以
标记字符范围,例如0-9表示0到9之间的所有数字。
//下面的\w匹配字母或数字或下划线。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的邮箱是Spark.eric@imooc.com";
preg_match($p, $str, $match);
echo $match[0];
正则表达式中每个元字符匹配一个字符,当使用+之后将会变的贪婪,它将匹配尽可能多的字符,但使用
问号?字符时,它将尽可能少的匹配字符,既是懒惰模式。
贪婪模式:在可匹配与可不匹配的时候,优先匹配
//下面的\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
注:关于match数组的说明:
文档上的解释为:如果提供了参数 matches ,它将被填充为搜索结果。 $matches[0] 将包含完整模式
匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。
文档上对于子组的说明为:子组通过圆括号分隔界定,并且它们可以嵌套。
如果正则表达式写为$p = '/\w+\s\w+/';,则没有子组,$matches[1]为空,而$matches[0]包含所匹配
的文本;但是将表达式加上括号写为$p = '/(\w+\s\w+)/';,则有了子组,此时$matches[1]与
$matches[0]相同。
使用正则表达式的目的是为了实现比字符串处理函数更加灵活的处理方式,因此跟字符串处理函数一样,
其主要用来判断子字符串是否存在、字符串替换、分割字符串、获取模式子串等。
PHP使用PCRE库函数来进行正则处理,通过设定好模式,然后调用相关的处理函数来取得匹配结果。
preg_match用来执行一个匹配,可以简单的用来判断模式是否匹配成功,或者取得一个匹配结果,他的
返回值是匹配成功的次数0或者1,在匹配到1次以后就会停止搜索。
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //结果为:Array ( [0] => def )
上面的代码简单的执行了一个匹配,简单的判断def是否能匹配成功,但是正则表达式的强大的地方是
进行模式匹配,因此更多的时候,会使用模式:
$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //结果为:Array ( [0] => abcd [1] => bc )
通过正则表达式可以匹配一个模式,得到更多的有用的数据。
正则匹配常用在表单验证上,一些字段会有一定的格式要求,比如用户名一般都要求必须是字母、数字
或下划线组成,邮箱、电话等也都有自己的规则,因此使用正则表达式可以很好的对这些字段进行验证:
<?php
$user = array(
'name' => 'spark1985',
'email' => 'spark@imooc.com',
'mobile' => '13312345678'
);
//进行一般性验证
if (empty($user)) {
die('用户信息不能为空');
}
if (strlen($user['name']) < 6) {
die('用户名长度最少为6位');
}
//用户名必须为字母、数字与下划线
if (!preg_match('/^\w+$/i', $user['name'])) {
die('用户名不合法');
}
//验证邮箱格式是否正确
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
die('邮箱不合法');
}
//手机号必须为11位数字,且为1开头
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
die('手机号不合法');
}
echo '用户信息验证成功';
会话控制(session与cookie)
Cookie是存储在客户端浏览器中的数据,我们通过Cookie来跟踪与存储用户数据。一般情况下,
Cookie通过HTTP headers从服务端返回到客户端。多数web程序都支持Cookie的操作,因为Cookie是
存在于HTTP的标头之中,所以必须在其他信息输出以前进行设置,类似于header函数的使用限制。
PHP通过setcookie函数进行Cookie的设置,任何从浏览器发回的Cookie,PHP都会自动的将他存储在
$_COOKIE的全局变量之中,因此我们可以通过$_COOKIE['key']的形式来读取某个Cookie值。
PHP中的Cookie具有非常广泛的使用,经常用来存储用户的登录信息,购物车等,且在使用会话Session时
通常使用Cookie来存储会话id来识别用户,Cookie具备有效期,当有效期结束之后,Cookie会自动的从
客户端删除。同时为了进行安全控制,Cookie还可以设置域跟路径,我们会在稍后的章节中详细的讲解他们。
实例:
ob_start();//打开输出控制缓冲
print_r($_COOKIE);
$content = ob_get_contents();//复制缓冲区内容到$content中
$content = str_replace(" ", ' ', $content);
ob_clean();//清空(擦掉)输出缓冲区
header("content-type:text/html; charset=utf-8");
echo '当前的Cookie为:<br/>';
echo nl2br($content);//nl2br 在字符串所有新行之前插入 HTML 换行标记
文件系统
一般情况下在对文件进行操作的时候需要先判断文件是否存在,PHP中常用来判断文件存在的函数有两个:
is_file与file_exists.
$filename = './test.txt';
if (file_exists($filename)) {
echo file_get_contents($filename);
}
如果只是判断文件存在,使用file_exists就行,file_exists不仅可以判断文件是否存在,同时也可以判断
目录是否存在,从函数名可以看出,is_file是确切的判断给定的路径是否是一个文件。
$filename = './test.txt';
if (is_file($filename)) {
echo file_get_contents($filename);
}
文件有很多元属性,包括:文件的所有者、创建时间、修改时间、最后的访问时间等。
fileowner:获得文件的所有者
filectime:获取文件的创建时间
filemtime:获取文件的修改时间
fileatime:获取文件的访问时间
其中最常用的是文件的修改时间,通过文件的修改时间,可以判断文件的时效性,
经常用在静态文件或者缓存数据的更新。
$mtime = filemtime($filename);
echo '修改时间:'.date('Y-m-d H:i:s', filemtime($filename));
通过filesize函数可以取得文件的大小,文件大小是以字节数表示的。
$filename = '/data/webroot/usercode/resource/test.txt';
$size = filesize($filename);
如果要转换文件大小的单位,可以自己定义函数来实现。
function getsize($size, $format = 'kb') {
$p = 0;
if ($format == 'kb') {
$p = 1;
} elseif ($format == 'mb') {
$p = 2;
} elseif ($format == 'gb') {
$p = 3;
}
$size /= pow(1024, $p);
return number_format($size, 3);
}
$filename = '/data/webroot/usercode/code/resource/test.txt';
$size = filesize($filename);
$size = getsize($size, 'kb'); //进行单位转换
echo $size.'kb';
值得注意的是,没法通过简单的函数来取得目录的大小,目录的大小是该目录下所有子目录以及文件大小的总和,
因此需要通过递归的方法来循环计算目录的大小。
与读取文件对应,PHP写文件也具有两种方式,最简单的方式是采用file_put_contents。
$filename = './test.txt';
$data = 'test';
file_put_contents($filename, $data);
上例中,$data参数可以是一个一维数组,当$data是数组的时候,会自动的将数组连接起来,
相当于$data=implode('', $data);
同样的,PHP也支持类似C语言风格的操作方式,采用fwrite进行文件写入。
$fp = fopen('./test.txt', 'w');
fwrite($fp, 'hello');
fwrite($fp, 'world');
fclose($fp);
跟Unix系统命令类似,PHP使用unlink函数进行文件删除。
unlink($filename);
删除文件夹使用rmdir函数,文件夹必须为空,如果不为空或者没有权限则会提示失败。
rmdir($dir);
如果文件夹中存在文件,可以先循环删除目录中的所有文件,然后再删除该目录,
循环删除可以使用glob函数遍历所有文件。
foreach (glob("*") as $filename) {
unlink($filename);
}
异常处理
从PHP5开始,PHP支持异常处理,异常处理是面向对象一个重要特性,PHP代码中的异常通过throw抛出,
异常抛出之后,后面的代码将不会再被执行。
当代码中使用了try catch的时候,抛出的异常会在catch中捕获,否则会直接中断。
1、基本语法
try{
//可能出现错误或异常的代码
//catch表示捕获,Exception是php已定义好的异常类
} catch(Exception $e){
//对异常处理,方法:
//1、自己处理
//2、不处理,将其再次抛出
}
PHP具有很多异常处理类,其中Exception是所有异常处理的基类。
Exception具有几个基本属性与方法,其中包括了:
message 异常消息内容
code 异常代码
file 抛出异常的文件名
line 抛出异常在该文件的行数
其中常用的方法有:
getTrace 获取异常追踪信息
getTraceAsString 获取异常追踪信息的字符串
getMessage 获取出错信息
如果必要的话,可以通过继承Exception类来建立自定义的异常处理类。
//自定义的异常类,继承了PHP的异常基类Exception
class MyException extends Exception {
function getInfo() {
return '自定义错误信息';
}
}
try {
//使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。
但是如果异常被触发,会抛出一个异常。
throw new MyException('error');//这里规定如何触发异常。注意:每一个 "throw" 必须对应
至少一个 "catch",当然可以对应多个"catch"
} catch(Exception $e) {//"catch" 代码块会捕获异常,并创建一个包含异常信息的对象
echo $e->getInfo();//获取自定义的异常信息
echo $e->getMessage();//获取继承自基类的getMessage信息
}
一般的异常处理流程代码为:
try {
throw new Exception('wrong');
} catch(Exception $ex) {
echo 'Error:'.$ex->getMessage().'<br>';
echo $ex->getTraceAsString().'<br>';
}
echo '异常处理后,继续执行其他代码';
数据库操作
PHP中一个数据库可能有一个或者多个扩展,其中既有官方的,也有第三方提供的。像Mysql常用的扩展有原生
的mysql库,也可以使用增强版的mysqli扩展,还可以使用PDO进行连接与操作。
不同的扩展提供基本相近的操作方法,不同的是可能具备一些新特性,以及操作性能可能会有所不同。
mysql扩展进行数据库连接的方法:
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
mysqli扩展:
$link = mysqli_connect('mysql_host', 'mysql_user', 'mysql_password');
PDO扩展
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
PHP要对数据库进行操作,首先要做的是与数据库建立连接,通常我们使用mysql_connect函数进行数据库连接
该函数需要指定数据库的地址,用户名及密码。
$host = 'localhost';
$user = 'code1';
$pass = '';
$link = mysql_connect($host, $user, $pass);
PHP连接数据库的方式类似于直接在命令行下通过进行连接,类似:mysql -hlocalhost -ucode1 -p,
当连接成功以后,我们需要选择一个操作的数据库,通过mysql_select_db函数来选择数据库。
mysql_select_db('code1');
通常我们会先设置一下当前连接使用的字符编码,一般的我们会使用utf8编码。
mysql_query("set names 'utf8'");
通过上面的步骤,我们就与数据库建立了连接,可以进行数据操作了。
在数据库建立连接以后就可以进行查询,采用mysql_query加sql语句的形式向数据库发送查询指令。
$res = mysql_query('select * from user limit 1');
对于查询类的语句会返回一个资源句柄(resource),可以通过该资源获取查询结果集中的数据。
$row = mysql_fetch_array($res);
var_dump($row);
默认的,PHP使用最近的数据库连接执行查询,但如果存在多个连接的情况,
则可以通过参数指令从那个连接中进行查询。
$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); //从第一个连接中查询数据
当我们了解了如何使用mysql_query进行数据查询以后,那么类似的,
插入数据其实也是通过执行一个sql语句来实现,例如:
$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); //执行插入语句
在mysql中,执行插入语句以后,可以得到自增的主键id,通过PHP的mysql_insert_id函数可以获取该id。
$uid = mysql_insert_id();
这个id的作用非常大,通常可以用来判断是否插入成功,或者作为关联ID进行其他的数据操作。
PHP操作数据库跟MySql客户端上操作极为相似,先进行连接,然后执行sql语句,再然后获取我们想要的结果集
PHP有多个函数可以获取数据集中的一行数据,最常用的是mysql_fetch_array,可以通过设定参数来更改
行数据的下标,默认的会包含数字索引的下标以及字段名的关联索引下标。
$sql = "select * from user limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
可以通过设定参数MYSQL_NUM只获取数字索引数组,等同于mysql_fetch_row函数,如果设定参数为
MYSQL_ASSOC则只获取关联索引数组,等同于mysql_fetch_assoc函数。
$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM); //这两个方法获取的数据是一样的
$row = mysql_fetch_assoc($result);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
如果要获取数据集中的所有数据,我们通过循环来遍历整个结果集。
$data = array();
while ($row = mysql_fetch_array($result)) {
$data[] = $row;
}
我们了解到通过循环可以获取一个查询的所有数据,在实际应用中,我们并不希望一次性获取数据表中的所有
数据,那样性能会非常的低,因此会使用翻页功能,每页仅显示10条或者20条数据。
通过mysql的limit可以很容易的实现分页,limit m,n表示从m行后取n行数据,在PHP中我们需要构造m与n
来实现获取某一页的所有数据。
假定当前页为$page,每页显示$n条数据,那么m为当前页前面所有的数据,既$m = ($page-1) * $n,
在知道了翻页原理以后,那么我们很容易通过构造SQL语句在PHP中实现数据翻页。
$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;
}
在上面的例子中,我们使用了$m与$n变量来表示偏移量与每页数据条数,但我们推荐使用更有意义的变量名
来表示,比如$pagesize, $start, $offset等,这样更容易理解,有助于团队协作开发。
数据的更新与删除相对比较简单,只需要构建好相应的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 '删除成功';
}
对于删除与更新操作,可以通过mysql_affected_rows函数来获取更新过的数据行数,如果数据没有变化,
则结果为0。
$sql = "update user set name = '曹操' where id=2 limit 1";
if (mysql_query($sql)) {
echo mysql_affected_rows();
}
当数据库操作完成以后,可以使用mysql_close关闭数据库连接,默认的,当PHP执行完毕以后,
会自动的关闭数据库连接。
mysql_close();
虽然PHP会自动关闭数据库连接,一般情况下已经满足需求,但是在对性能要求比较高的情况下,
可以在进行完数据库操作之后尽快关闭数据库连接,以节省资源,提高性能。
在存在多个数据库连接的情况下,可以设定连接资源参数来关闭指定的数据库连接。
$link = mysql_connect($host, $user, $pass);
mysql_close($link);
网友评论