php基础内容和常见操作函数

数组的操作

print_r 对数组进行解析不带下标

echo 和 print_r 都可以解析变量

array_keys 返回数组字段带下标

array_values返回数组字段值带下标

array_map 同 js 高阶函数

array_search 返回数组索引

unset 销毁变量数组元素

函数的操作

函数只能访问内部变量

如果需要访问外部变量需要使用关键字

global

php常量
DIRECTORY_SEPARATOR   定义目录分隔符
API
implode()  转为字符串并拼接
basename() 返回路径的文件名, 参数二如果文件有扩展名,将不会显示这个扩展名
var_dump()  输出带有类型的值
memory_get_usage()   PHP输出占用内存量
instanceof 判断一个对象是否是这个类的实例  2.判断一个对象是否实现了这个接口
serialize  序列化  返回a:3:{i:0;s:6:"Google";i:1;s:6:"Runoob";i:2;s:8:"Facebook";} 
unserialize 反序列化     Array ( [0] => Google [1] => Runoob [2] => Facebook ) 
empty() 判断一个变量是否被认为是空的
mysql API
mysqli_affected_rows(); 返回被影响的行数   >0   0表示没有   -1 查询返回错误
mysqli_field_count 返回最近的列数
mysqli_num_rows 返回结果行的数量
mysqli_fetch_assoc  返回对联数组
mysqli_fetch_array  数维数组
mysqli_fetch_all(res,type)   返回一个二维数组   类型 MYSQLI_ASSOC MYSQLI_NUM MYSQLI_BOTH
Fn API
is_array()   函数搜索数组中是否存在指定的值
file API
file_put_contents('./test.test','变量'); 生成一个测试文件
file_put_contents('a test file path');  获取测试文件内容
require(dirname(__FILE__).'/../php/postting-mysql/mysqlDO.php'); 文件引入(以自己为根目录访问)
getcwd()  拿到当前所在绝对路径C:\WAMP\www\test\code\App
dirname() 取出文件目录
basename()   取出文件名带后缀
file_exista()  判断文件是否存在
in_file()  判断是否为一个文件
tr API
substr  返回字符串的一部分
ucfirst  首字母大写
strtolower  转小写
strtoupper 转大写
strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
implode()函数返回一个由副本元素组合成的字符串
number_format() 函数通过千位分组来格式化数字
is_uploaded_file()函数检查指定的文件是否是通过HTTP POST上传的
is_numeric()函数用于检测变量是否为数字或数字字符串
replace()  替换
img API
imagecreate()  创建canvas 
imagecreatetruecolor()  创建支持真彩色的画布
imagecolorallocate()  给画布分配颜色
imagejpeg  gif png    显示图片
imagefill()  填充图片
iamgesx()  画布的宽度
iamgesy()   画布的长度
imagefontwidth height   字体的宽度
imagestring()  将字符串  显示在画布上
imagecreatefromjpeg() 打开创建图片资源
imagettfbbox() 测定中文字体的范围
imagettftext() 将中文字体写到图片上
imagecope() 图片拷贝
imagedestroy() 销毁图片资源
imagecopyresampled() 拷贝图片并缩放大小

多字节处理
将中文字体显示到画布上
重点:
  使用中文  必须开启多字节
  开启扩展
  extenstion = php_mbstring.dll
  开启后函数带mb  为处理多字节函数
file API
enctype="multipart/form-data"   必须标明文件上传的规则
is_dir()   检查指定的文件是否是一个目录  如果目录存在返回 true
mkdir()  创建目录  Boolean
$_FILES["file"]["name"] - 上传文件的名称
$_FILES["file"]["type"] - 上传文件的类型
$_FILES["file"]["size"] - 上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码


---------
file_get_contents()   打开文件流
file_put_contents()函数把一个字符串写入文件中
filemtime(filename)  获取文件创建后的修改时间
date API
date();
uniqid() 函数基于以微妙计的当前事件,生成一个唯一的ID unique 

魔术方法
    __construct()   构造函数
    __destruct()   抽象函数
    __clone()   不充许克隆
    __tostring() 当类被作为字符串访问时执行
    __invoke()  当类被作为函数调用时执行
    __set($k,$v)  给无法访问的属性赋值时调用
    __get($k)        访问无法访问的属性时调用
    __isset($k)    判断无法访问的属性是否存在时调用
    __unset($k)  销毁无法访问的属性是调用
    __call():调用无法访问的方法时自动执行
    __callstatic():调用无法访问的静态方法时自动执行
    __sleep()    序列化的时候自动调用 return array 序列化的字段名
    __wakeup()   反序列化的时候自动调用  $this->type='学生' 每次反序列都添加一个type属性
namespace 命名空间

不能混合带括号的名称空间声明和不带括号的名称空间声明

是一个类,命名空间必须是程序脚本的第一条语句

const关键字只能在类中声明

define函数不能再类中

再同一个文件中可以声明多个namespace
1.写法:
namespace MyProject{
推荐用大括号
}
namespace {
全局代码是一个不带名称的namespace
}
2.在声明命名空间之前唯一合法的代码时用于定义源文件编码方式的declare语句。所有非PHP代码包括空白符都不能出现在命名空间的声明之前

<?php declare(encoding="utf-8"); ?>

子命名空间
与目录和文件的关系很像,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义:
namespace MyProject\Sub{
}


4.访问方法

<?php namespace Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {} class foo { static function staticmethod() {} } /* 非限定名称 */ 在自身命名空间内访问 foo(); // 解析为函数 Foo\Bar\foo foo::staticmethod(); // 解析为类 Foo\Bar\foo ,方法为 staticmethod echo FOO; // 解析为常量 Foo\Bar\FOO /* 限定名称 */ 子空间内访问 subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo, // 以及类的方法 staticmethod echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO /* 完全限定名称 */ 全局 访问 \Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO ?>

命名空间引入
namespace China\Beijing\Shuny;
function getInfo(){
echo ‘李白’;
}
namespace USA;
function getInfo(){
echo ‘Lincoln’;
}
use China\Beijing\Shuny;
getInfo(); // Lincoln
Shuny\getInfo(); //李白
引入命名空间的拼接规制
公共空间+引入空间+(去除公共部分,公共部分只有一级)空间元素
China\Beijing\Shuny+Shuny\getInfo()

引入空间元素
引入类 use China\Beijing\Shunyi\Student; stydent为类
引入函数 use function China\Beijing\Shunyi\getInfo; getInfo为类 [php7.0以上支持]
引入常量 use const China\Beijing\Shunyi\TYPE TYPE为类 [php7.0以上支持]

给类,函数取别名
引入的类和函数与当前空间的类和函数名称相同,需要给引入的类和函数取别名。
通过as取别名
<?php
引入类取别名 use China\Beijing\Shunyi\Student as ChinaStudent;
映入函数 use function China\Beijing\Shunyi\getInfo as info1;
用别名的实例和调用

面向对象
三大特性:
1.封装:  实用性,工具
2.继承:    extends 关键字    子类继承父类   (没钱找父要)
3.多态: 多态的发生必须是由继承关系,并且子类要重写父类方法
多态是指父类对象拥有子类形态,并且可以表现出子类的特性(调用子类方法)
  • 类使用 class 关键字后加上类名定义。

  • 类名后的一对大括号({})内可以定义变量和方法。

  • 类的变量使用 var 来声明, 变量也可以初始化值。

  • 函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。

  • 变量 $this 代表自身的对象。

    PHP_EOL 为换行符

函数
方法一:
    class Site{
        var $title;
        function set($pre){
            #$this为本身需要引用初始化传值 (容器里面加东西)
            $this->title = $pre;
        }
        function get(){
            echo $this->title;
        }
    }
    $test = new Site;
    $test->set('www.baidu.com');
    $test->get()    // www.baidu.com
方法二:构造函数
    class Site1{
        var $url;
        var $title;
        function __construct($pre,$pre1){
            #初始化 $this 
            $this->url = $pre;
            $this->title = $pre1;
        }
        function get(){
            echo $this->url;
            echo $this->title;
        }
}
    $test1 = new Site1('www.baidu.com','百度');
    $test1->get() // www.baidu.com百度
方法三:折构函数
    class Site2{
        function __construct(){
            print "构造函数";
            $this->name = "MySiteClass";
        }
        function __destruct(){
            print "销毁".$this->name;  //在执行中访问
        }
}
$obj = new Site2;
对象
1.继承extends
class chile extends parent {

}
2.访问控制

PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。

  • **public(公有):**公有的类成员可以在任何地方被访问。

  • **protected(受保护):**受保护的类成员则可以被其自身以及其子类和父类访问。

  • **private(私有):**私有的类成员则只能被其定义所在的类访问。

    class MyClass {
        public $public = 'Public';
        protected $protected = "protected";
        private $private = 'private';
        var $var="var";  定义的变量为公有变量
    }
    
    3.接口 interface

    使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

    接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。

    接口中定义的所有方法都必须是公有,这是接口的特性。

    要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

声明一个接口
interface iTemplate{
    ...code
}
实现接口
class Template implements iTemplate{
    ...code
}
4.常量
在定义常量不需要使用$符号
<?php
class MyClass{
    const constant = '常量值';
    function showConstant(){
        echo self::constant;
    }
}
//访问方式
#方式一:
echo MyClass::constant;
#方式二:
$classname = "MyClass";
echo $classname::constant;
#方式三:
$class = new MyClass();
$class->showConstant();
echo $class::constant;
?>
5.抽象类
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
6.Static关键字
声明类属性或方法为 static(静态),就可以不实例化类而直接访问。 
静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
静态属性不可以由对象通过 -> 操作符来访问
7.Final 关键字
PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
8.调用父类构造方法
PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct() 。
9.self
self是用来代替类名的,与范围解析操作符::一起使用
class Salf{
     private static $count = 0 ;  #私有,不充许外部直接访问
     private function __construct(){
         #私有,不充许外部实列化(因为对象不能外部调用)
     }
     public static function self(){
        echo Self::$count;
        echo self::$count;
        return new self(); #使用self关键字实列化
     }
 } 
 $s =Salf::self();
 var_dump($s);
类中的API
get_class()  获取当前类名
class_exists() 检查类是否定义
include_once  
file_exists() 判断文件是否存在

类的加载
1.手动加载类文件
Saler.php
    class Saler{}
userSaler.php
    class Saler{
    }
    if(!class_exists('Saler')){
            #没有这个Saler 类就引入
    }
    $s = new Saler();  #调用的是本文件内先
2.自动加载
function __autoload($a){
    #$a   形参代表的是一个类名
    $file = $a.'.php';
    if(!class_exists($file)) include $a;
}
$b = new Buyer();
$s = new Saler();
$s2 = new Saler();
3.自定义函数实现加载类
//自定义函数实现对象调用
    function my_autoload($classname){
        if(!class_exists($classname)){
            echo __FUNCTION__;
            $file =  $classname.'.php';
            if(file_exists($file)){
                include $file;
            }
        }
    }
    // 自定函数需要用spl_autoload_register()  自动加载机制让函数调用
    spl_autoload_register('my_autoload');
    $s = new Saler();
    注意:只有一个函数找不到后面的函数都不在执行
对象克隆

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odt1Aslv-1660662086156)(C:\Users\Administrator\Desktop\clone.PNG)]

<?php
class Saler{
    public $count;
    private $money;
    public function __clone(){
        // var_dump($this);
        $this->money = 10;
    }
}
$s1 = new Saler();
$s1->count = 1;
$s2 = clone $s1;
var_dump($s1,$s2);
?>
C:\WAMP\www\test\code\php\useSaler.php:13:
object(Saler)[1]
  public 'count' => int 1
  private 'money' => null

C:\WAMP\www\test\code\php\useSaler.php:13:
object(Saler)[2]
  public 'count' => int 1
  private 'money' => int 10

如果不充许对象被克隆,可以将__clone()方法私有化(本质是不充许对象在外部被克隆)
private function __clone () {
}
$s2 = clone $s1;  // 无效报错
小结:克隆出来的是一个新的对象;
克隆魔术方法是系统内部自己定义的方法__clone()
在对象被克隆后,新克隆出来的对象会自动调用
PHP继承
继承:extends ,是指子类通过继承可以访问父类的成员
父类:也叫基类,是较大的分类
子类:也叫派生类,比父类的分类要小
有限继承
 class Ren {
        public $public = 'public';
        protected $protected = 'protected';
        private $private = 'private';
        public function public(){
            echo $this->public;
        }
        protected function protected(){
                // echo $this->protected;
        }
        private function private(){
            echo $this->private;
        }
        protected function getmony(){
            echo $this->private;
        }

    }
    class Man extends Ren {
        #访问受保护的内容
       public function getProtected(){
           echo $this->protected;
        //    $this->protected();
       } 
       public function getprivate(){
              //私有绑定对象名 需要父开放接口才能进行访问
           $this->getmony(); 
       }
    }
    $m = new Man();
    var_dump($m); //证明父类属性确实被子类继承
    $m->public(); // 公有属性被访问  
    $m->getProtected();  //受保护的属性不能直接访问 在这个对象中  需要提取
    $m->getprivate(); //父类私有属性除非父类提供能继承的方法访问
重写
1.属性子类覆盖父类 (私有除外)
2.方法访问的是实列本身的方法
3.子类的权限不能高于父类
4.在方法参数一致不单单要求数量一致而且数据类型要球也必须相同,但形参名字可以不同;
php7以前重写对于参数这块没有要求。
5.私有方法不存在以上规制
6.静态成员也可以被重写,但是静态属性不会被覆盖(属于类,不属于对象)
parent关键字
1.子类继承父类
2.子类重写父类方法
3.子了重写的方法内部需要访问父类成员或者需要访问父类成员
4.使用parent访问父类方法
    class DB{
        protected $link;
        public function __construct(){
            $this->link = mysqli_connect('localhost','root','12345678','student');
            echo __METHOD__;
        }
    }
    class table extends DB {
        public function __construct(){
            parent::__construct();
            // 子类调用父类中被覆盖的方法在进行操作
             echo __METHOD__;   //DB::__constructtable::__construct
        }
    }
静态延迟吧绑定
1.静态绑定self::    static::  静态延迟绑定
2.静态延迟绑定是不确定引用的类
3.静态延迟绑定的意义是用来保证访问的静态成员是根据调用类的不同而选择不同的表现
4.如果没有则不变
final最终类
final class Man{}
1.final关键字修饰的类表示无法被继承
2.final关键字海可以修饰方法,表示方法不能子类重写(通常类不会使用final关键字)
3.final修饰类表示不希望类在出现子类,可以恒昊保护类的内部结构不被暴露(可以有效控制继承链)
4.final修饰方法表示不希望方法被修改,可以在一个更高的维度来保证同类事务的共同表现
class Human{
    public function show(){

    }
    public final function walk(){

    }
}
class Ran extends Human{
    public function show(){

    }
    public function walk(){
        //报错 final不可被重写
    }
}
抽象类abstract
使用abstract关键字修饰的类,表示该类只能被继承,不能被实列化
抽象类只是用来规范下属类的基本结构,本身不可被实例化
抽象类只能被实现类继承
abstract关键字可以修饰方法,表示方法为抽象方法抽象方法没有方法体(没有{})
    抽象方法存在的类必须为抽象类
    继承抽象类的类要么为抽象类要么实现抽象类里所有的抽象方法
抽象类还可以有其他类该有的任何成员
    //抽象类
    abstract class Human{
        //普通方法
        public function show(){

        }
        //抽象方法
        public abstract function eat();   //定义抽象方法
    }
    #不能被实列化
    // new Human();
    // 2.继承类
    abstract class Woman extends Run{
        // 抽象方法只能被抽象类继承
    }
    class Run extends Human{
        #实现父类抽象方法
        public function eat(){

        }
    }
    $m = new Run();  // 可以实列化
    注意:抽象类的抽象方法因为要被继承才能实列化所以   不能有私有方法
PHP trait代码复用
trait :为类似PHP的单继承语言而准备的一种代码复用机制
trait可以使得单继承语言摆脱复用而不得不继承的尴尬,让面向对象变得更加纯粹
类的继承应该本身之间具有相似性(包含)
有些不同类的类却拥有公共的方法
    为了实现代码复用就要增加公共类,然后继承(为了继承而继承,不纯粹合面向对象)
    提供公共代码让具有共性类引入(trait)
      // start 基本使用
    #定义 trait
    trait Eeit{
        public $time;
        protected $how;
        private $info;
        public function showTime(){
            echo 'eat';
        }
        protected function showHow(){
            echo $this->how;
        }
        private function showInfo(){
            echo $this->info;
        }
        // abstract public function abstractMethod();  trait中有抽象方法得用 抽象方法访问
        // const IP = 3.1475858;  不能有类常量
    }
    trait S{
        public function sleep(){
            echo 'sleep';
        }
    };
    // new Eeit();  不能被实列
    //类中的使用
    class Human{
        use Eeit,S;  //多个trait 类
    }
    $h=new Human();
    $h->showTime();
    $h->sleep();
trait同名
trait同名分为两类
    属性同名:不充许出现同名属性,不管是多个trait还是类内部出现同名属性(除非同名通值)
    方法同名:不充许同名出现,使用替代方法确定要用的那个
    使用insteado 明确需要用的那个
    使用别名临时修改同名中的一个
trait t1{
    public $name = true;
    public $age = 1;
    public function eat(){
        echo 't1:eat';
    }
}
trait t2{
    public $name = true;
    // public $age = 0;
    public function eat(){
        echo 't2:eat';
    }
}
class  Human
{
    // use t1,t2    报错同名不同值
    #同名方法的解决
    use t1,t2{
        t2::eat insteadOf t1;   //强制替换t2下的eat 方法
        t1::eat as s;
    }
    // 同名方法都引用使用别名的方法(注意:别名是复制了方法)
}
$m = new Human();
$m->eat();
$m->s();
trait控制权
//  直接改变权限
    trait t1{
       public function base(){
        echo '可以访问';
       }
       private function pee(){
        echo '不可以访问';
       }
    }
    class Ruman{
        use t1{
            t1::pee as public;    //改变权限
            t1::base as private;
        }
    }
$s = new Ruman();
$s->pee();
// $s->base();   改为私有不可外部访问
//该别名权限
class changeAll{
    use t1{
        base as private b;
        pee as public p;
    }
}
$a = new changeAll();
// $a->b();  //别名方法私有化不能调用
$a->base();  //别名修改不会将原有方法撤换:原有访问修饰限定符都不会受任何牵连;

trait优先级
trait在引入的过程中可能存在本身或者父类拥有同名成员
trait同名属性必须保证同名同值,否则报错
trait同名方法系统认定为重写,优先级关系为:子类>traot>父类
如果子类,trait和父类都有同名方法:子类中使用parent也只访问到父类
trait Eat{
public function eat(){
echo ‘Eat::eat’; //trait 的优先级比父类高
parent::eat(); //调用继承父类
}
}
class Human{
public function eat(){
echo ‘Human::eat’;
}
}
class Man extends Human{
use Eat;
// public function eat(){ //类本身的优先级最高
// parent::eat();
// echo ‘Eat::eat’;
// }
// public function eat(){ //类本身的优先级最高
// parent::eat();
// echo ‘Man::eat’;
// }
}
$m = new Man();
$m->eat();

接口
接口:interface 与类类似,专门用来规范一些共性类必须实现的方法
    接口不是类但是与类有类似的结构
    接口不能实列化,类可以实现接口
    语法:
        interface  名字{}
        class 类名 implements 接口名字{}
接口成员规范
    interface Human{
        const NAME = '人';
        public function eat();
        public static function show();
        接口中的方法必须为抽象方法 不用abstract   不能有属性静态也不能  接口方法必须都是公有抽象方法
    }
实现接口:实体类
方法一:
class Many implements Human{
    #必须实现接口所有的抽象方法
    public function eat(){

    }
    public static function show(){

    }
}
方法二:
abstract class Woman implements Human{

}
接口继承:接口可以被接口继承
    接口继承接口的目的
        实现接口的成员扩展:丰富接口内容,从而实现更好的对实现类的规范
        为了形成完成的接口体系,让不同级别的类实现不同级别的接口
    接口可以一次性继承多个接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nc7Q79XW-1660662086157)(C:\Users\Administrator\Desktop\interface.PNG)]

重载 overload
overload 指在一个类中可以出现多个同名方法,彼此之间的参数个数和类型不一样
重载在强类型语言中,可以灵活的应对不同的需求(参数类型不同)
PHP中不支持同名方法,而且也不区分数据类型(弱类型语言),所以PHP不支持传统重载
PHP中的重载:当某些不充许操作发生时,会自动调用的一种内部机制(相关的魔术方法),来实现错误处理
    属性重载:属性不存在或者权限不够访问的时候自动触发
    方法重载:方法不存在或者权限不够访问的时候自动触发
所有PHP的重载都需要开发者事先定义好:实现魔术方法
PHP属性重载:当对象访问不存在的或者权限不够的属性的时候,自动触发的魔术方法让代码不出错(容错处理)
    属性重载魔术方法
        __get(属性名):访问不存在或者权限不够的属性时触发
        __set(属性名,属性值) :设置不存在或者权限不够的属性时触发
        __isset(属性名):判定不存在或权限不够的属性时触发
        __unset(属性名):删除不存在或者权限不够的属性时触发

__get

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eTeP4yve-1660662086158)(C:\Users\Administrator\Desktop__get()].PNG)

php方法重载
对象或者类访问不存在或者权限不够的方法时,自动触发的魔术方法让代码不出错
    方法重载魔术方法
        __call(方法名,方法参数列表):调用不存在或者权限不够的方法时触发
        __callStartic(方法名,方法参数列表):调用不存在或者权限不够的静态方法时触发
对象遍历
1.对象遍历:将对象中的所有属性以键值对的形式取出并进行访问
    对象是一种复合数据类型,对象中真正保存的内容是属性
    对象的属性本质也是一种键值对关系:名字=值
    对象遍历就是利用foreach对对象中的属性进行取出解析
        对象遍历遵循访问修饰限定符的限定:即类外只能遍历所有公有属性
    foreach (对象变量 as [属性名变量 => ] 属性值变量){
        属性名变量代表取出的每个属性的名字
        属性值变量代表取出的每个属性的值
    }
 class Man{
        public $name = 'lilei';
        public $height = 178;
        public $weight = 140;
        protected $age = 30;
        private $money = 50;
        public function getForeach(){
            foreach ($this as $k=>$v){
                echo $k.":".$v;
            }
        }
    }
    $m = new Man();
    foreach($m as $k=>$v){
        echo $k.":".$v;
        // name:lileiheight:178weight:140
    }
    $m->getForeach();  //name:lileiheight:178weight:140age:30money:50
1.类内不循环遍历都可以
2.外部只能循环公有属性
2.Iterator迭代器:php内置的一种能够修改froeach 内部运行机制的接口
    lterator迭代器内置了5各抽象方法,实现迭代器的类必须实现5个抽象方法
    实现了Lterator迭代器的类的对象在进行foreach时,不会按照foreach原来的机制处理,而是调用     迭代器的5个方法
foreach 本身的执行步骤
    1.初始化目标:将对象指针指向第一个属性(执行一次)
    2.判定指针是否有效:判定当前指针指向的元素是否存在,存在下一步,不存在终止(n+1次执行)
    3.取出当前指针元素下标(属性名):将当前属性的名字取出来储存到变量(n次执行)
    4.取出当前指针元素值(属性值):将当前属性的值取出来储存到变量(n次执行)
    5.将指针指向下一个:将取出元素后的指针指向下一个属性(n次执行)
lterator迭代器的本质就是改变foreach内部的五个方式,实现开发者的自定义控制
2.1简单迭代控制(针对索引数组)
    class Person implements Iterator{
    private $properties = ['name','age','gender','height','weight'];
    private $key = 0;
    // 实现五个方法
    public function current(){
        echo __METHOD__;
        //取出当前数组元素值
        return $this->properties[$this->key];
    }
    public function key(){
        echo __METHOD__;
        //返回当前下标   
        return $this->key;
    }
    public function next(){
        echo __METHOD__;
        //不需要返回值:当前下标 +1
        $this->key++;
    }
    public function rewind()
    {
        echo __METHOD__;
        //不需要返回值:重置数组下标         
        $this->key=0;
    }
    public function valid(){
        echo __METHOD__;
        //需要返回布尔值:判定下标对应的元素是否存在即可
        return isset($this->properties[$this->key]);
    }
}
$p = new Person();
foreach($p as $k=>$v){
    echo $k.":".$v.'<br>';
}
执行顺序
Person::rewindPerson::validPerson::currentPerson::key0:name
Person::nextPerson::validPerson::currentPerson::key1:age
Person::nextPerson::validPerson::currentPerson::key2:gender
Person::nextPerson::validPerson::currentPerson::key3:height
Person::nextPerson::validPerson::currentPerson::key4:weight
Person::nextPerson::validPerson::valid

2.2 复杂迭代控制(针对全部数组)
class Person implements Iterator{
    private $info = [
        'name' => '',
        'age' => 0,
        'gender' =>'',
        'height' =>,
        'weight' =>0
    ]
}
生成器 generator,生成器提供了一种更容易的方法来实现简单的对象迭代
    想比较定义类实现Iterator 接口的方式,性能开销和复杂性大大降低
    生成器是一个类Generator实现了iterator 接口,并且实现了lterator方法(修改了内部逻辑)
    生成器是暂停循环执行逻辑,等到使用到的时候才触发循环再次执行

1.普通数组的遍历
        function getarr(){
        $arr = [];
        for($i=0;$i<10000;$i++){
            $arr[]=$i;
        }
        return $arr;
    }
    echo memory_get_usage(); // 3563200
    $g = getarr();
    foreach($g as $v){
        echo $v." ";
    }
    echo memory_get_usage(); //753776
    注:内存的占用

2.generator 生成器的遍历
 function getarr(){
        for($i=0;$i<10000;$i++){
          yield $i;
        }
    }
    $g = getarr();
  echo memory_get_usage(); //3600080
    foreach($g as $v){
        echo $v."";
    }
  echo memory_get_usage();   //
  注意:内存消耗的减少
  生成器的母的是利用yield 关键字实现循环内部的暂停,而直到yield被使用使用循环才会继续执行,从而节省通过循环生产一个大数组的过程,最终实现内存优化
设计模式
单例模式(singleton pattern):单列模式就是设计的模式最多只能得到一个对象
单列模式的设计规范就是 ‘三私-公’:
    私有化构造方法:禁止在类外无限实例化对象
    私有化克隆方法:禁止对象无限克隆对象
    私有化静态属性:保存类内部实例化得到的对象
    公有化静态方法:充许外部通过类内部方法获取对象

        class singletion{
        #私有化构造方法:防止外部无限实例化对象
        private function __construct(){
        }
        // 静态属性:私有化,保存已经产生的对象
        private static $obj = null;
        #公有静态方法:产生对象返回给外部调用者
        public static function getInstance(){
            if(!self::$obj instanceof self){
                self::$obj = new self();
            }
            return self::$obj;
        }
        private function __clone(){    
        }
    }
    $s1 = singletion::getInstance();
    $s2 = singletion::getInstance();
        // $s3 = clone $s2;
    var_dump($s1,$s2);
工厂模式: factory 是指像工厂一样流水线生产对象,由一个地方对象,其他位置就不许哟啊额外实列化对象,从而可以方便后期代码统一的维护
1.普通工厂模式
2.静态工厂模式
3.方便用户控制的工厂模式
  class Men{
        function display(){
            echo '我是Men类';
        }
    }
    class Women{
        function display(){
        echo '我是Women类0';
        }
    }
    //工厂类大类
    class factory{
        public static function getFactory($classname){
            // if(!class_exists($classname)) return null; 
            return new $classname;
        }
    }
    $g = factory::getFactory('Men');
    $g->display();
注意:工厂模式的方法是实现对实列化的灵活控制
 测类模式
 class Walk{
        public function way() {
            echo '我走着';
        }
    };
    class Bus{
        public function way(){
            echo "坐车去";
        }
    }
    class Student{
        public function paly($obj){
            $obj->way();
        }
    }
    $m = new Student();
    $m->paly(new Walk());
    $m->paly(new Bus());
PDO
学习别人写好的类的使用掌握 PDO类对数据库的操作,并且能够基于PDO进行二次封装来实现更快捷的项目开发
PDO:php data object ,是一种纯面向对象的数据库操作扩展
    PDO在PHP5以后的版本增加,是目前通用的PHP操作数据库的扩展
    PDO能够支持多种数据库操作,不限定数据库产品类型
    PDO是一种纯面向对象的操作,有三个类
        PDO类:初始化和sql执行
        PDOStatement类:结果解析
        PDOException类:异常处理
PDO加载
    1.PDO是一种外部提供的扩展,PHP如果想直接调用,需要加载扩展
    2.PDO因为支持产品很多,所以分解成PDO支持扩展和PDO对应数据库产品的支持,PDO扩展在PHP5以后自动开启,而数据库产品的支持需要开发者根据实际项目所有数据库来选择性开启
    找到版本的PHP文件中的php.ini 配置文件

开启扩展

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2DQSSb5-1660662086158)(C:\Users\Administrator\Desktop\PDO.PNG)]

重启

验证

<?php
    phpinfo();
?>

成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VUHjSfDr-1660662086158)(C:\Users\Administrator\Desktop\PDO1.PNG)]

PDO操作
PDO类和PDOStatement类的基本操作,实现数据的增删改查
    PDO手册查阅
    PDO类基本应用
    PDO 写操作
    PDO查询操作
    PDO事务功能
    PDO异常处理
PDO 类基本应用
PDO类虽然提供了很多方法,但是常用的方法有以下几个
    PDO::_construct():实例化PDO对象:帮助实现连接认证,数据库选择,字符集设置
    PDO::exec():执行一个写操作SQL指令,返回受影响的行数
    PDO::query() :执行一个读操作sql 指令,返回一个PDOstatement类对象(后者进行数据解析操作)
    PDO::errorCode()和PDO::errorInfo() :获取上次错误的信息(错误码和错误描述数组)
    PDO::lastInsertId(); 获取新增记录的自增长ID 
    #实例化PDO对象
    $pdo = new PDO('mysql:host=localhost;dbname=cmp','root','12345678');
    //  数据库的连接      用户  密码
    #写操作
    var_dump($pdo);
    $sql = "delete fromstu1";
    $rows = $pdo->exec($sql);   // 返回受影响的行数   否则返回false
    var_dump($rows);
    #读操作执行
    if($rows == false){
        echo '错误代码为'.$pdo->errorCode();
        echo '错误原因为'.$pdo->errorInfo()[2];
        // errorInfo返回数组 2下标代表错误具体信息
        // 错误信息为MySQL处理错误信息
        exit;
        // 错误不需要继续执行代码
    }
    $sql = 'select * from stu2';
    $stmt = $pdo->query($sql)
    // print_r($stmt);
PDO查询操作
PDO::query() 方法只能执行sql,并不能直接解析结果,返回以恶PDOStatement类对象
PDOStatement::fetch()系列方法从对象中实现数据获取
    fetch:获取一条记录
    fetchAll:获取全部记录
$fetch_style = PDO::FETCH_ASSOC 查询规制的改变
PDO事务功能
#开启事务
$pdo->beginTransaction() or die('事务开启失败');
#执行事务
$pdo->exec('insert into stu values()');
#设置回滚点
$pdo->exec('savepoint spl')
#回滚
$pdo->exec('rollback to spl')
#终止事务
$pdo->commit(); //成功提交
$pdo->rollback();  //失败回滚
PDO预处理
PDO预处理:是PDO封装一套特定的方法,在方法中做了一些优化操作,是的开发人员可以便捷的用来实现预处理
PDO预处理的是现实基于MySQL预处理机制,只是针对预处理的操作过程进行了内部封装
    预处理占位符 ?,也可以使用PDO占位符:名字
PDO中预处理提供了一套方法机制,主要由以下几个方法组成
    PDO::prepare():发送预处理指令,只需要提供要执行的指令即可,不需要prepare名字from 成功得PDOStatement类对象,失败得到一个false(或者异常错误)
    PDOStatement::bindParam():绑定预处理所需要得参数,只能绑定变量(引用传递)
    PDOStatement::bindValue():绑定预处理所需要的参数,可以绑定值(值传递)
    PDOStatement::execute():执行预处理,成功返回true,失败返回false

        $pdo = new PDO('mysql:host=localhost;dbname=cmp','root','12345678') or die('数据库连接失败');
     $pre_sql = "select * from bank"; #无数据预处理指令
     $pre_sql = 'select * from bank where card = ?'; #有参数预处理指令
     $pre_sql = 'select * from bank where card = :id'; #PDO特定预处理参数指令(:+字符串),更明确
     #发送预处理指令
     $stmt = $pdo->prepare($pre_sql);
     $stmt->bindValue(':id', 1001); #直接绑定数值
     $id = 2 ;
     $stmt->bindValue(':id', $id); #绑定变量数据
     #绑定预处理参数:bindParam
     #$stmt->bindParam('id',1);  错误:第二个参数要求必须为变量(引用传递)
     $id = 1002;
      $stmt->bindParam(':id', $id);  #必须是传递变量  返回的是布尔值

      #执行预处理
      $res = $stmt->execute();
      var_dump($res);  #返回的是布尔值不能真正的拿到返回的数据
      #如果是查询预处理:需要PDOStatement::fetch() 才能查出结果
      $row = $stmt->fetch(PDO::FETCH_ASSOC);
      var_dump($row) ;

      #错误处理
      if($row === false){
          echo $pdo->errorCode();
          echo $pdo->errorInfo()[2];
          exit;
      }
PHP异常机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Xm4s6KZ-1660662086159)(C:\Users\Administrator\Desktop\error.PNG)]

PDO错误机制
PDO错误机制:指PDO在使用过程中出现了错误(大多是SQL指令执行错误) 的时候,PDO处理错误的方式
    PDO中提供了三种错误机制,是通过PDO的常量PDO::ATTR_ERRMODE来选择的
    PDO::ERRMODE_SILENT:静默模式,出错了不处理(默认的)
    PDO::ERRMODE_WARNING:警告模式,出错了立马给出错误提示
    PDO::ERRMODE_EXCEPTION:异常模式,出错了讲错误交给异常PDOException对象

#静默模式:默认模式
    $pdo = new PDO('mysql:host=localhost;port=3306;dbname=db_2','root','root');
    $pdo->exec(); #不会报错

#警告模式
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
$pdo->exec();   #会报错

#异常模式
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
try{
    #PDO中的所有的错误发生都会产生一个PDOException 类对象
    $pdo->exec();  #错误:被捕捉到
}catch(PDOException $e){
    #进入到异常处理
        echo '来了';
}
Cookie
cookie是保存在客户端的信息包(一个文件)
通过header() setcookie() 操作响应头
header('content-type:charset=gbk');
header('name:tom');  数据不会被客户端保存
setcookie('name','tom') ; //键值对 
header('Set-Cookie:name=tom'); 同上

获取Cookie
echo $_COOKIE[''];

永久性cookie
    说明:关闭浏览器后cookie的值不消失
        给cookie添加过期时间就形成了永久性cookie 过期时间            是时间类型是时间戳
            $time=time() + 3600;
            setcookie('name','tom',$time); 

cookie一般在访问时只有在当前目录 和子目录保存  上级目录不会保存
    设置全网站访问
    setcookie('name','tom',0,'/');

支持子域名
    每个域名代表一个网站,网站之间的cookie是不可以相互访问的
    二级域名的网站,cookie实现共享
        setcokie('name','tome',0,'/','baidu.com');
        域名一: www.bb.baidu.com
        域名二: www.aa.baidu.com

是否安全传输
    默认情况下,http和https都能
    安全传输:只能充许https 进行访问
    setcookie('name','tom',0,'/',true);

是否安全访问
    默认情况下,php和js都可以访问cookie
    安全访问:只有PHP可以访问
    setcookie('name','tom',0,'/',true,true);

删除cookie
setcookie('name',false);
setcookie('name');
setcookie('name','tom',time()-1)

cookie的缺点
    1.在浏览器中可以看到cookie的值,所以安全性低
    2.只能保存字符串和数字,所以可控性差
    3.数据放在请求头中传输,增加了请求时候的数据负载
    4.数据储存在浏览器中,但浏览器储存空间是有吸限制的,一般是4k
Session 会话
    seesion_start()  
        作用:没有会话空间就创建一个空间
            有会话空间就打开空间
  $_SESSION['name'] = 'tom'; //设置session
    echo $_SESSION['name'];   //获取session值
    // echo session_id();  获取session编号

与会话有关的配置
    session.save_path = ""; 结对路径   session储存路径
    session.auto_start = 1 session自动开启,默认不自动开启
    session.save_handler = files 会话以文件的形式保存
    session.gc_maxlifetime = 1440 会话的生命周期是1440秒
    -------- 
    session.name = PHPSESSID
    session.cookie_path = /   会话编号整站有效
    session.cookie_domain =   会话编号在当前域名下有效

销毁会话
    session_start();
    session_destroy() 销毁会话

垃圾回收
    1.会话文件超过了生命周期是垃圾文件
    2.PHP自动进行垃圾回收
    3.垃圾回收的概率默认是1/1000

禁用cookie对session的影响
    默认情况下,session只依赖于cookie,session的编号只能通过cookie传输
    可以设置session,不仅仅依赖于cookie
        session.use_only_cookies = 0   //session 不仅仅依赖于cookie
        session.use_trans_sid = 1    //充许通过其他方式传递session_id
            设置后,PHP自动添加get和post 传递session_id
session会话入库
session默认情况下储存到文件中,我们可以将session储存到数据库中
session入库可以解决哪些问题?
1. 可以解决跨域操作
2. 可以实现单点登陆
3. 可以统计在线人数
4. 可以实现同一时只允许一个用户在线
创建sess表
如果用了text类型就不能使用memory引擎
create table sess(
    -> sess_id varchar(50) primary key comment '会话编号',
    -> sess_value text comment '会话值',
    -> sess_time int unsigned not null comment '会话产生时间'
    -> )engine=innodb charset=utf8 comment '会话表';

 memory引擎数据存储在内存中
create table sess(
    sess_id varchar(50) primary key comment '会话编号',
    sess_value varchar(2000) comment '会话值',
    sess_time int unsigned not null comment '会话产生时间'
    )engine=memory charset=utf8 comment '会话表';

    memory引擎的注意事项
        1.memory引擎数据存储在内存中,速度快但是重启服务器后数据清空
        2.memory引擎中的字段不可以是text类型



 //打开会话
    function open(){
        global $link;
        $link = mysqli_connect('localhost','root','12345678','student');
        mysqli_set_charset($link,'utf8');
        return true;
    }
    //删除会话
    function close(){
        echo 'close'."<br>";
        return true;
    }
    //读取会话
    function read($sess_id){
        global $link;
        $sql = "select sess_value from sess where sess_id='$sess_id'";
        $rs = mysqli_query($link,$sql);
        $rows = mysqli_fetch_row($rs);
        return (string)$rows[0];
    }
    //写入会话
    function write($sess_id,$sess_value){
        global $link;
        $sql = "insert into sess values('$sess_id','$sess_value',unix_timestamp()) on duplicate key update sess_value='$sess_value',sess_time=unix_timestamp()";
        return mysqli_query($link,$sql);
    }
    //销毁会话
    function destroy($sess_id){
        global $link;
        $sql = "delete from sess where sess_id='$sess_id'";
        return mysqli_query($link,$sql);
    }
    // 垃圾回收
    function gc($lifetime){
        global $link;
        $expires = time() - $lifetime;
        $sql = "delete from sess where sess_time<$expires";
        return mysqli_query($link,$sql);
    }
    // 更改会话存储
    session_set_save_handler('open','close','read','write','destroy','gc');
    //开启会话
    session_start();
    // session_destroy();
    // 写入时唯一键和主键器冲突所以要进行更新操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0CKAx2lz-1660662086159)(C:\Users\Administrator\Desktop\session.PNG)]

session垃圾回收设置  php.ini配置文件内更改
        session.gc_probability = 1000  设置启动垃圾回收程序的概率
        session.cookie_lifetime = 0   会话编号的过期时间
    默认是 1 / 1440
    在重新打开页面时回收上一个session会话
自动加载类
方法一:
 function __autoload($class_name){
        require "./{$class_name}.class.php";
    }   //返回的是实例化的类名
     $books = new Book();
    $books->setName('面向对象');
    $phone = new Phone();
    $phone->setName('6s');
    $books->getName();
    $phone->getName();
    自动调用__autoload()函数,并且将缺少的类名作为参数传递给__autoload();    注意:__autoload()函数在PHP7.2以后就不支持了

方法二:
    spl_autoload_register(); 注册加载类函数
        2.1
            function loadClass($class_name){
                require "./{$class_name}.class.php";
            }
            spl_autoload_register('loadClass');
        2.2 
            spl_auto_register('dome1');
            spl_auto_register('dome1');
            spl_auto_register('dome1');
        2.3
            spl_autoload_register(function($class_name){
                require "./{$class_name}.class.php";
            }) ;
加载不规制类(不同文件夹内)
    spl_autoload_register(function($class_name)){
        $map= array(
        //键值对
                'Goods' => './aa/Goods.class.php'
            )
        if(isset($map[$class_name]){
            require $map[$class_name];
        }
    }
数组的序列化和反序列化
   // 数组的序列化 
// $sites = array('Google', 'Runoob', 'Facebook');
// $serialized_data = serialize($sites);  //a:3:{i:0;s:6:"Google";i:1;s:6:"Runoob";i:2;s:8:"Facebook";} 
// file_put_contents('./test.test',$serialized_data);


    // 数组的反序列化
    $str = file_get_contents("./test.test");
    $stu = unserialize($str);   //返回一个数维数组
    print_r($stu);
对象的序列化和反序列化
对象的反序列化需要有类的参与,如果没有类在反序列化时候无法确定类
简写语句
<?php for($i=1;$i<=$var;$i++):?>
    <a href=''><?=$i?></a>
<?php endfor;?>
配置文件php.ini short_open_tag 为no
字符串
echo <<<str
    html
    {变量}
str;    独占一行 
smarty
模板引擎 
对页面 HTML PHP 进行分离
smarty/smarty.class.php
    class Smarty
{
    public $template_dir = './templates/';  // 模板目录
    public $templatec_dir = './templates_c/'; // 混合目录
    // 赋值
    private $tpl_var = array();
    public function assign($k, $v)
    {
        $this->tpl_var[$k] = $v;
    }
    public function compile($tpl)
    {
        $tpl_file = $this->template_dir.$tpl;   
        $con_file = $this->templatec_dir.$tpl.'.php';
        if (file_exists($con_file) && filemtime($tpl_file) < filemtime($con_file))
            require $con_file;
        else {
            $str = file_get_contents($tpl_file);
            $str = str_replace('{$', '<?php echo $this->tpl_var[\'', $str);
            $str = str_replace('}', '\'];?>', $str);
            file_put_contents($con_file, $str);
            require $con_file;
        }
    }
}


view/xxx.html     //模板块
     {$title}DFDFDFDFD
viewc/xxx.html.php  //混合模块

index.php    //接口模块
  require './smarty/Smarty.class.php';
   $smarty = new Smarty;
   $smarty->template_dir='./view/';
   $smarty->templatec_dir='./viewc/';
   $smarty->assign('title','ss');
   $smarty->compile('index.html');
Smarty

详细 https://www.w3cschool.cn/smarty/

简单使用
    创建目录
    require './Smarty/Smarty.class.php';
    $smarty = new Smarty()
    $smarty->assign();  定义数据
    $smarty->left_delimiter=''; 定义边界符
    $smarty->right_delimiter='';
    $smarty->setTemplateDir() ; 设置模板目录
    $smarty->setComplieDir();设置混编目录
    $smarty->displa(); 定义接口位置

smarty 注释
    {*这是smarty注释*}  在源码中不显示
smarty 变量

​ smarty中变量有三种,普通,配置,保留

普遍变量
一: 普通变量
    1.1 在PHP中定义
    $smarty->assign('name','tom');
二: 可以在模板定义
    {assign var='变量名' value='值'};
    简化 
        {$'变量名'='值'};
保留变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L93unajz-1660662086159)(C:\Users\Administrator\Desktop\手册\smarter保留变量.PNG)]

配置变量

从配置文件中获取变量,配置文件默认的是文件夹是configs

在configs 目录下创建smarty.conf 文件

configs/smarty.conf

color='#00000'
size=20px

index.php 模板中调用

 引入配置文件{config_load file='smarty.conf'}  全局
 {
     color:{#color#};
     font-szie:{$smarty.config.size}
 }

配置文件中的节

​ 1.全局变量写在节的前面

​ 2.配置文件中[] 表示节

​ 3.配置文件中的注释是#

color=#00000
size=20px

[spring]
color=#00000
size=20px

[winter]
color=#00000
size=20px

在模板中的使用 index.html

{$config_load file='smarty.conf' section='winter'}
运算符

​ smarty中运算符是PHP是一样的。除此以外,smarty还支持如下的运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bt76Jrl8-1660662086160)(C:\Users\Administrator\Desktop\手册\运算符.PNG)]

判断
{if is_numeric($smarty.get.score)}
    {if $smarty.get.score gte 90}
        A
    {elseif $smarty.get.score gte 90}
        B
    {else}
        C
{/if}
数组

smarty中访问数组的方式有两种

数组[下标]
数组.下标

PHP代码

<?php
    require './Smarty/smarty.class.php';
    $samrty = new Smarty();
    $stu = array('tom','berry')
    $emp=array('name'=>'rose','sex'=>'女')
    $goods= array(
        array('name'=>'手机','price'=>22),
        array('name'=>'钢笔','price'=>10)
    )
    $smarty->assign('stu',$stu);
    $smarty->assign('emp',$emp);
    $smarty->assign('goods',$goods)

html 模板

学生:{$stu[0]}-{$stu.1}
雇员: {$emp['name']} - {$emp.sex}
商品:
    {$goods[0]['name']}
    {$goods[0].price}
    {$goods.1['name']}
    {$goods.1.price}
循环

​ smarty 中支持有 {for} {while} {foreach}{section}

1. for

语法:

{for 初始值 to 结束值 [step] 步长}
{/for}
默认步长是1

例题

{for $i=1 to 5}
    {$i} : xx
{/for}

{for $i=1 to 5 step 2}
    {$i}:xxx
{/for}
2 while

语法

{while 条件}
{/while}

例题

{$i=1}
{while $i<=5}
    {$i++} :xxx
{/while}
3.foreach

语法:

{foreach 数组 as $k=$v}
{foreachlse}
    没有数组输出
{/foreach}

foreach的属性

@index:从0开始的索引
@iteration:从1开始的编号
@first:是否是第一个元素
@last:是否是最后一个元素

phpd代码

$stu = array('first'=>'xx','second'=>'xx','third'=>'xx')
$smarty.assign('stu',$stu)
<tr>
    <th>是否是第一个元素</th>
    <th>索引</th>
    <th>编号</th>
    <th>键</th>
    <th>值</th>
    <th>是否是最后一个元素</th>
</tr>
{foreach $stu as $k=>$v}
<tr>
    <td>{$v@first}</td>
    <td>{$v@index}</td>
    <td>{$v@iteration}</td>
    <td>{$k}</td>
    <td>{$v}</td>
    <td>{$v@last}</td>
</tr>
{foreachelse}
    没有输出
{/foreach}
4.section

section 不支持关联数组,只能遍历索引数组

{section name=自定义名字 loop=数组}
{/section}

例题:

php

<?php
require './Smarty/smarty.class.php'
$smarty = new Smarty()
$smarty->assign('stu',array('tom','berry'))
$smarty->display('');

html

<tr>
    <th>是否是第一个元素</th>
    <th>索引</th>
    <th>编号</th>
    <th>值</th>
    <th>是否是最后一个元素</th>
</tr>
{section name=s loop=>$stu}
<tr>
    <td>{$smarty.section.s.firs}</td>
    <td>{$smarty.section.s.index}</td>
    <td>{$smarty.section.s.iteration}</td>
    <td>{$stu[s]}</td>
    <td>{$smarty.section.s.last}</td>
</tr>
{foreachelse}
    没有输出
{/foreach}
函数

函数有两种,自定义函数和内置函数

smarty 的内置函数就是封装的PHP关键字

变量修饰器

​ 变量修饰器

变量修饰器的本质就是PHP函数,用来转换数据

PHP代码

<?php
require './Smarty/smarty.class.php'
$smarty = new Smarty()
$smarty->display('5-demo.html')

html 代码

转成大写:{'abc'|upper} 
转成小写:{'ABC'|lower}
默认值:{$add|default:'地址不详'}
去除标签:{'<b你好吗</b>'|strip_tags}
实体转换:{'<b>你好吗</b>'|escape}
日期:{$smarty.now|date_format:'%Y-%m-%d %H:%M:%S'}

1.将PHP的关键字或函数封装成标签称为函数,将PHP关键字封装成smarty关键字称为修饰器,内部的本质都是。PHP函数或PHP关键字

2.|称为管道运算符,将前面的参数传递后面的修饰器使用

自定义变量修饰器

变量修饰器存放在plugins目录中

​ 规制:

​ 1.文件的命名规制:modifier.变量修饰器名称.php

​ 2.文件内方法命名规制:smarty_modifier_变量修饰器名称(形参…){}

​ 列题

​ 1.在plugins 目录中创建modifier.cal.php页面

<?php
    function smarty_modifier_cal($num1,$num2,$num3){
        return $num1+$num2+$num3;
    }
?>

​ 2.在模板中调用

{10|cal:20:30}

10作为第一个参数
参数之间用:隔开
避免Smarty解析
smarty的定界符和css js 中的大括号产生冲突的时候,css,js 中的大括号不要被smarty解析
方法一:更换定界符
方法二:左大括号后面添加空白字符
方法三:{literal}{/literal}
smarty不解析{/literal}{/literal} 中的内容
{literal}
    body{
        color:#FF0000;
    }
{/literal}
缓存

缓存:页面缓存,空间缓存,数据缓存。smarty中的缓存就是页面缓存

开启缓存
$smarty->caching=true|1;   //开启缓存

缓存的更新

方法一:删除缓存,系统会重新生成新的缓存文件

方法二:更新了模板文件,配置文件,缓存自动更新

方法三:过了缓存的生命周期默认是3600

方法四:强制更新

PHP代码

$samrty->caching=true; 开启缓存
if(date('H')>=9)
    $samrty->force_cache=true;  //强制缓存
$smarty->display()
缓存的生命周期
$smarty->cache_lifetime=-1 | 0 | N
-1:永远不过期
0:立即过期
N:有效期是N秒,默认是3600秒

PHP代码

$smarty->cache_filetime=3  //缓存的生命周期
局部不缓存
局部不缓存有两种方法
1.变量不缓存 {$变量名 nocache}
2.整个块不缓存 {nocache} {/nocache}

代码

不缓存 :{$smarty.now nocache}
不缓存:{nocache}
    {$smarty.now}
{/nocache}
缓存分页

通过$smarty->display(模块,识别id) 通过识别id来缓存分页,集合

require './Smarty/smarty.class.php'
$smarty = new Smarty()
$smarty->caching=1
$smarty->display('',$_GET['pageno'])

html 页面

这是第{$smarty.get.pageno}
清除缓存
$smary->clearCache
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值