PHP进阶(一)

一、数组

  • 1、数组的声明:$arr = array();
  • 2、数组的初始化:
    PHP有两种数组:索引数组、关联数组。
  • 索引数组:索引数组是指数组的键是整数的数组,并且键的整数顺序是从0开始,依次类推。
    索引数组赋值:
    1、用数组变量的名字后面跟一个中括号的方式赋值,当然,索引数组中,中括号内的键一定是整数。比如,$arr[0]='苹果';
    2、用array()创建一个空数组,使用=>符号来分隔键和值,左侧表示键,右侧表示值。当然,索引数组中,键一定是整数。比如,array('0'=>'苹果');
    3、用array()创建一个空数组,直接在数组里用英文的单引号'或者英文的双引号"赋值,数组会默认建立从0开始的整数的键。比如array('苹果');这个数组相当于array('0'=>'苹果');
    获取数组中的值:
<?php
//从数组变量$arr中,读取键为0的值
$arr = array('苹果','香蕉');
$arr0=$arr['0'];
if( isset($arr0) ) {print_r($arr0);}
?>
//通过for循环
<?php
$fruit=array('苹果','香蕉','菠萝');
for($index=0; $index<3; $index++){
    echo '<br>数组第'.$index.'值是:'.$fruit[$index];
}
?>
//通过froeach循环
<?php
$fruit=array('苹果','香蕉','菠萝');
foreach($fruit as $key=>$value){
    echo '<br>第'.$key.'值是:'.$fruit[$key];
}
?>
  • 关联数组:关联数组是指数组的键是字符串的数组。
    初始化:
$fruit = array(
    'apple'=>"苹果",
    'banana'=>"香蕉",
    'pineapple'=>"菠萝"
);
<?php
//创建一个关联数组,关联数组的键“orange”,值是“橘子”
$fruit=array('orange'=>"橘子");
print_r($fruit['orange']);
?>

赋值:
第一种:用数组变量的名字后面跟一个中括号的方式赋值,当然,关联数组中,中括号内的键一定是字符串。比如,$arr['apple']='苹果';
第二种:用array()创建一个空数组,使用=>符号来分隔键和值,左侧表示键,右侧表示值。当然,关联数组中,键一定是字符串。比如,array('apple'=>'苹果');
访问数组:

<?php
//从数组变量$arr中,读取键为apple的值
$arr = array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");
$arr0=$arr['apple'];
if( isset($arr0) ) {print_r($arr0);}
?>
//通过foreach访问
<?php
$fruit=array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");
foreach($fruit as $key=>$value){
    echo '<br>键是:'.$key.',对应的值是:'.$value;
}
?>

二、函数

  • 1、定义方式:
  • 1.使用关键字“function”开始
  • 2.函数名可以是字母或下划线开头:function name()
  • 3.在大括号中编写函数体:
function name() {
    echo 'Eric';
}
//在这里调用函数
name();
  • 2、返回值
    使用return关键字可以使函数返回值,可以返回包括数组和对象的任意类型,如果省略了 return,则默认返回值为 NULL。
function add($a) {
    return $a+1;
}
$b = add(1);

返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。返回结果同上。

function add($a) {
    return $a+1;
    $a = 10;
    return $a+20;
}
$b = add(1);

函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。

function numbers() {
    return array(1, 2, 3);
}
list ($one, $two, $three) = numbers();
  • 3、可变函数
    通过变量的值来调用函数,因为变量的值是可变的,所以可以通过改变一个变量的值来实现调用不同的函数。经常会用在回调函数、函数列表,或者根据动态参数来调用不同的函数。可变函数的调用方法为变量名加括号。
<?php
function func() {
    echo 'my function called.';
}
$name = 'func';
//调用可变函数
$name();
//my function called.

可变函数也可以用在对象的方法调用上。

class book {
    function getName() {
        return 'bookname';
    }
}
$func = 'getName';
$book = new book();
$book->$func();
  • 4、内置函数
    内置函数指的是PHP默认支持的函数,PHP内置了很多标准的常用的处理函数,包括字符串处理、数组函数、文件处理、session与cookie处理等。
    字符串替换:
<?php
$str = '苹果很好吃。';
//请将变量$str中的苹果替换成香蕉
$str = str_replace('苹果', '香蕉', $str);
echo $str;
  • 5、判断函数是否存在
    使用function_exists判断一下函数是否存在。同样的method_exists可以用来检测类的方法是否存在。
<?php
function func() {
    echo 'exists';
}
$name = 'func';
if (function_exisits('func')) { //判断函数是否存在
    $name();
}
//类是否定义可以使用class_exists
class MyClass{
}
// 使用前检查类是否存在
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
//文件是否存在file_exists
$filename = 'test.txt';
if (!file_exists($filename)) {
    echo $filename . ' not exists.';
}

三、类和对象

<?php
//定义一个类
class Car {
    var $name = '汽车';
    function getName() {
        return $this->name;
    }
}

//实例化一个car对象
$car = new Car();
$car->name = '奥迪A6'; //设置对象的属性值
echo $car->getName();  //调用对象的方法 输出对象的名字
  • 1、对象的创建
    受保护的属性与私有属性不允许外部调用,在类的成员方法内部是可以调用的。默认都为public,外部可以访问。一般通过->对象操作符来访问对象的属性或者方法,对于静态属性则使用::双冒号进行访问。当在类成员方法内部调用的时候,可以使用$this伪变量调用当前对象的属性。
$car = new Car();
//也可以采用变量来创建
$className = 'Car';
$car = new $className();
  • 2、类的方法
    使用关键字static修饰的,称之为静态方法,静态方法不需要实例化对象,可以通过类名直接调用,操作符为双冒号::。
class Car {
    public static function getName() {
        return '汽车';
    }
​}
echo Car::getName(); //结果为“汽车”
  • 3、构造函数和析构函数
    使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用该函数,因此常用来在对象创建的时候进行一些初始化工作。在子类中如果定义了__construct则不会调用父类的__construct,如果需要同时调用父类的构造函数,需要使用parent::__construct()显式的调用。
    使用__destruct()进行定义,析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。
<?php
class Car {
    //增加构造函数与析构函数
    function _construct(){
        echo "构造函数执行";
    }
    function _destruct(){
        echo "析构函数执行";
    }
}
class Truck extends Car{
    function __construct(){
        print "子类构造函数被调用 \n";
        parent::__construct();
    }
    function __destruct(){
        print "子类析构函数被调用 \n";
        parent::__destruct();
    }  
}
$car = new Car();
unset($car);
$truck = new Truck();
unset($truck);
?>
  • 4、静态Static
    静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用。静态属性不允许对象使用->操作符调用。静态方法中,$this伪变量不允许使用。可以使用self,parent,static在内部调用静态方法与属性。
class Car {
    private static $speed = 10;
    public static function getSpeed() {
        return self::$speed;
    }
}
echo Car::getSpeed();  //调用静态方法
 //动态调用静态方法
$func = 'getSpeed';
$className = 'Car';
echo $className::$func(); 
  • 5、访问控制
    如果构造函数定义成了私有方法,则不允许直接实例化对象了,这时候一般通过静态方法进行实例化,在设计模式中会经常使用这样的方法来控制对象的创建,比如单例模式只允许有一个全局唯一的对象。
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(){
        $this->speed=parent::speedUp()+50;
    }
}
$car = new Truck();
$car->speedUp();
echo $car->speed;
  • 6、重载
    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;

方法重载:

<?php
class Car {
    public $speed = 10;

    //在这里使用重载实现speedDown方法
    public function _call($name,$args){
        if($name=='speedDown'){
            $this->speed-=10;
        }
    }
}
$car = new Car();
$car->speedDown(); //调用不存在的speedDown方法
echo $car->speed;
  • 7、高级特性
    对象比较:当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,当需要判断两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断。
class Car {
}
$a = new Car();
$b = new Car();
if ($a == $b) echo '==';   //true
if ($a === $b) echo '==='; //false

对象复制:在一些特殊情况下,可以通过关键字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);

四、字符串

  • 1、单引号和双引号的区别
    PHP允许我们在双引号串中直接包含字符串变量。
    而单引号串中的内容总被认为是普通字符。
$str='hello';
echo "str is $str"; //运行结果: str is hello
echo 'str is $str'; //运行结果: str is $str
  • 2、去除字符串首尾的空格
    PHP中有三个函数可以去掉字符串的空格
    trim去除一个字符串两端空格。
    rtrim是去除一个字符串右部空格,其中的r是right的缩写。
    ltrim是去除一个字符串左部空格,其中的l是left的缩写。
<?php
$str="      左侧空格要去掉";
echo ltrim($str);
?>
  • 3、获取字符串的长度
    直接获取字符串的长度函数就是strlen()。strlen函数对于计算英文字符是非常的擅长,但是如果有中文汉字,可以使用mb_strlen()函数获取字符串中中文长度。
$str = 'hello';
$len = strlen($str);
echo $len;//输出结果是5
$str = "我爱你";
echo mb_strlen($str,"UTF8");//结果:3,此处的UTF8表示中文编码是UTF8格式,中文一般采用UTF8编码
  • 4、字符串的截取
  • 1、英文字符串的截取函数substr()
$str='i love you';
//截取love这几个字母
echo substr($str, 2, 4);//为什么开始位置是2呢,因为substr函数计算字符串位置是从0开始的,也就是0的位置是i,1的位置是空格,l的位置是2。从位置2开始取4个字符,就是love。
  • 2、中文字符串的截取函数mb_substr()
$str='我爱你,中国';
//截取中国两个字
echo mb_substr($str, 4, 2, 'utf8');//为什么开始位置是4呢,和上一个例子一样,因为mb_substr函数计算汉字位置是从0开始的,也就是0的位置是我,1的位置是爱,4的位置是中。从位置4开始取2个汉字,就是中国。中文编码一般是utf8格式
  • 5、查找字符串
    用PHP的查找字符串函数strpos();
<?php
//查找字符串
$str = 'What is your name?';
echo strpos($str,'name');
?>
//13:表示在第13个位置出现
  • 6、替换字符串
    用PHP的替换函数str_replace()
    函数说明:str_replace(要查找的字符串, 要替换的字符串, 被搜索的字符串, 替换进行计数[可选])
$str = 'I want to learn js';
$replace = str_replace('js', 'php', $str);
echo $replace;//结果显示I want to learn php
  • 7、格式化字符串
    用PHP的格式化字符串函数sprintf()
    函数说明:sprintf(格式, 要转化的字符串)
$str = '99.9';
$result = sprintf('%01.2f', $str);
echo $result;//结果显示99.90

1、这个 % 符号是开始的意思,写在最前面表示指定格式开始了。 也就是 "起始字符", 直到出现 "转换字符" 为止,就算格式终止。
2、跟在 % 符号后面的是 0, 是 "填空字元" ,表示如果位置空着就用0来填满。
3、在 0 后面的是1,这个 1 是规定整个所有的字符串占位要有1位以上(小数点也算一个占位)。如果把 1 改成 6,则 $result的值将为 099.90,因为,在小数点后面必须是两位,99.90一共5个占位,现在需要6个占位,所以用0来填满。
4、在 %01 后面的 .2 (点2) 就很好理解了,它的意思是,小数点后的数字必须占2位。 如果这时候,$str 的值为9.234,则 $result的值将为9.23.为什么4 不见了呢? 因为在小数点后面,按照上面的规定,必须且仅能占2位。 可是 $str 的值中,小数点后面占了3位,所以,尾数4被去掉了,只剩下 23。
5、最后,以 f "转换字符" 结尾。

  • 8、字符串的合并与分割
  • 1、php字符串合并函数implode()
    函数说明:implode(分隔符[可选], 数组)
    返回值:把数组元素组合为一个字符串
$arr = array('Hello', 'World!');
$result = implode('', $arr);
print_r($result);//结果显示Hello World!
  • 2、php字符串分隔函数explode()
    函数说明:explode(分隔符[可选], 字符串)
    返回值:函数返回由字符串组成的数组
$str = 'apple,banana';
$result = explode(',', $str);
print_r($result);//结果显示array('apple','banana')
  • 9、字符串的转义
    php字符串转义函数addslashes()
    函数说明:用于对特殊字符加上转义字符,返回一个字符串
    返回值:一个经过转义后的字符串
<?php
//字符串转义
$str = "what's this?";
echo addslashes($str);
?>
//what\'s this?

五、表达式

  • 1、正则表达式
    对字符串进行操作的一种逻辑公式,就是用一些特定的字符组合成一个规则字符串,称之为正则匹配模式。PHP中使用PCRE库函数进行正则匹配,比如下例中的preg_match用于执行一个正则匹配,常用来判断一类字符模式是否存在。
<?php
//请修改变量p的正则表达式,使他能够匹配苹果
$p = '/苹果/';
$str = "我喜欢吃苹果";
if (preg_match($p, $str)) {
    echo '匹配成功';
}

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 '匹配成功';
}
  • 2、元字符与转义
    正则表达式中具有特殊含义的字符称之为元字符,常用的元字符有:

\ 一般用于转义字符
^ 断言目标的开始位置(或在多行模式下是行首)
$ 断言目标的结束位置(或在多行模式下是行尾)
. 匹配除换行符外的任何字符(默认)
[ 开始字符类定义
] 结束字符类定义
| 开始一个可选分支
( 子组的开始标记
) 子组的结束标记
? 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词)
* 量词,0 次或多次匹配
+ 量词,1 次或多次匹配
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
{ 自定义量词开始标记
} 自定义量词结束标记
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

//下面的\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];
<?php
//请修改变量p的正则表达式,使他能够匹配str中的电话
 $p =  '/\d{3}-\d{8}/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0];
//先执行3次数字匹配,在匹配-,在匹配8次数字

举例:
\ba\w*\b
匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w),最后是单词结束处(\b)。
\d+匹配1个或更多连续的数字。这里的+是和
类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。
\b\w{6}\b
匹配刚好6个字符的单词。
元字符(和数字6在同一个键位上的符号)和$都匹配一个位置,这和\b有点类似。匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:
^\d{5,12}$
这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}匹配只能不多不少重复2次,{5,12}则是重复的次数不能少于5次,不能多于12次,否则都不匹配。
因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。
\(?0\d{2}[) -]?\d{8}
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。

  • 3、贪婪模式与懒惰模式
    正则表达式中每个元字符匹配一个字符,当使用+之后将会变的贪婪,它将匹配尽可能多的字符,但使用问号?字符时,它将尽可能少的匹配字符,既是懒惰模式。
    贪婪模式:在可匹配与可不匹配的时候,优先匹配
//下面的\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
  • 4、查找匹配
  • 1、匹配一次结果:preg_match
  • 2、匹配多个结果:preg_match_all可以循环获取一个列表的匹配结果数组。
$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches);
print_r($matches);
  • 5、搜索和替换
$string = 'April 15, 2014';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '$3, ${1} $2';
echo preg_replace($pattern, $replacement, $string); //结果为:2014, April 15

推荐阅读更多精彩内容

  • 一、数组 1、数组定义 数组就是一个键值对组成的语言结构,键类似于酒店的房间号,值类似于酒店房间里存储的东西。 $...
    空谷悠阅读 515评论 4 12
  • 常用函数 var_dump() 函数返回数组的数据类型和值 unset() 释放 bool define(stri...
    Scallions_阅读 238评论 1 2
  • 一、php可以做什么 php是一种可以在服务器端运行的编程语言,可以运行在Web服务器端。 php是一门后台编程语...
    空谷悠阅读 2,597评论 4 97
  • 一、字符串操作 PHP开发中,我们遇到最多的可能就是字符串。 一个字符串 通过下面的3种方法来定义: 1、单引号 ...
    空谷悠阅读 382评论 1 6
  • 发的晚了。最近心情不太好。
    vvan_s阅读 474评论 0 50