一、自动加载器
非自动加载方式
缺点:require太多
namespace admin;
echo '当前命名空间:'.__NAMESPACE__.'<br>';
//namespace是对当前命名空间的引用
// class Test
// {
// }
// $test = new namespace\Test();
require __DIR__.'/admin/controller/Demo1.php';
require __DIR__.'/admin/controller/Demo2.php';
require __DIR__.'/admin/controller/Demo3.php';
// use默认必须是“完全限定名称”,所以“\”全局空间标识符可以不写。
use admin\controller\Demo1;
use admin\controller\Demo2;
use admin\controller\Demo3;
// 访问三个控制器Demo1-3的index
// 完全限定名称,绝对路径。
// echo \admin\controller\Demo1::index().'<br>';
// echo \admin\controller\Demo2::index().'<br>';
// echo \admin\controller\Demo3::index().'<br>';
// 限定名称,相对路径。
// echo controller\Demo1::index().'<br>';
// echo controller\Demo2::index().'<br>';
// echo controller\Demo3::index().'<br>';
// 非限定名称,当前路径。
echo Demo1::index().'<br>';
echo Demo2::index().'<br>';
echo Demo3::index().'<br>';
自动加载器
解决require过多的问题
demo3.php代码
require __DIR__.DIRECTORY_SEPARATOR.'autoloader.php';
use admin\controller\Demo1;
use admin\controller\Demo2;
use admin\controller\Demo3;
// 非限定名称,当前路径。
echo Demo1::index().'<br>';
echo Demo2::index().'<br>';
echo Demo3::index().'<br>';
自动加载器autoloader.php代码
// 自动加载器
spl_autoload_register(function ($class){
require $class.'.php';
});
./controller/Demo1.php代码
<?php
/**
* 为实现自动加载器,应该遵循一些约定
* 1. 一个文件只有一个类。
* 2. 这个类名和文件名必须一致。
* 3. 这个类的命名空间,必须映射到类文件所在的路径。
*/
namespace admin\controller;
class Demo1
{
public static function index()
{
return __METHOD__;
}
}
./controller/Demo2.php代码
namespace admin\controller;
class Demo2
{
public static function index()
{
return __METHOD__;
}
}
./controller/Demo3.php代码
namespace admin\controller;
class Demo3
{
public static function index()
{
return __METHOD__;
}
}
运行demo3.php,结果:
trait
PHP默认是单继承,项目不大不必用接口实现多继承,父类子类继承方式会增加项目复杂度,可以用迷你版基类trait,trait可以看成一个通用组件插入到任何一个类中,实现类功能扩展。
<?php
namespace _0816;
echo '<hr>'.'经典的类继承:'.'<br>';
class A
{
public static function hello()
{
return __METHOD__;
}
}
class B extends A
{
}
// 调用方法
// echo B::hello();
// 完整类名
// echo B::class;
echo call_user_func([B::class,'hello']).'<br>';
echo '<hr>'.'使用接口实现多继承:'.'<br>';
interface iA
{
public static function hello();
}
interface iB
{
public static function world();
}
class W implements iA, iB
{
public static function hello()
{
return __METHOD__;
}
public static function world()
{
return __METHOD__;
}
}
echo call_user_func([W::class,'hello']).'<br>';
echo call_user_func([W::class,'world']).'<br>';
echo '<hr>'.'trait实现多继承:'.'<br>';
trait tA
{
public static function hello()
{
return __METHOD__;
}
}
trait tB
{
public static function world()
{
return __METHOD__;
}
}
class W1
{
use tA;
use tB;
}
echo call_user_func([W1::class,'hello']).'<br>';
echo call_user_func([W1::class,'world']).'<br>';
echo '<hr>'.'trait优先级:'.'<br>';
// 父类同名方法优先级 < trait类方法 < 自己类方法
class P
{
public static function hello()
{
return __METHOD__;
}
}
trait tC
{
public static function hello()
{
return __METHOD__;
}
}
class S extends P
{
// public static function hello()
// {
// return __METHOD__;
// }
use tC;
}
echo call_user_func([S::class,'hello']).'<br>';
echo '<hr>'.'trait命名冲突:'.'<br>';
trait t1
{
public static function hello()
{
return __METHOD__;
}
}
trait t2
{
public static function hello()
{
return __METHOD__;
}
}
class W3
{
//t1和t2同名hello命名冲突
// use t1;
// use t2;
use t1, t2
{
// 给t1引入别名,别名不影响任何方法,也不会重命名当前方法,所以阻碍不了冲突。
t1::hello as tttt;
// t2替代掉t1的方法,t1的hello方法被排除使用。
t2::hello insteadof t1;
}
}
echo call_user_func([W3::class,'hello']).'<br>';
echo '<hr>'.'trait优化:'.'<br>';
trait t3
{
public static function hello()
{
return __METHOD__;
}
}
trait t4
{
public static function world()
{
return __METHOD__;
}
}
trait t5
{
public static function say()
{
return __METHOD__;
}
}
trait t6
{
public static function ok()
{
return __METHOD__;
}
}
//优化在一个importAll中
trait importAll
{
use T3;
use T4;
use T5;
use T6;
}
class W4
{
use importAll;
}
echo call_user_func([W4::class,'hello']).'<br>';
echo call_user_func([W4::class,'world']).'<br>';
echo call_user_func([W4::class,'say']).'<br>';
echo call_user_func([W4::class,'ok']).'<br>';
数据库的基本操作
数据库配置
./config/database.php
<?php
// 数据库链接参数
return
[
// 数据库类型
'type' => 'mysql',
// 主机IP
'host' => 'localhost',
// 端口
'port' => '3306',
// 数据库名,不提供数据库名execute()执行不成功,errorCode()打印3D000
'dbname' => 'phpedu',
// 用户名
'username' => 'phpedu',
// 密码
'password' => 'phpedu',
// 字符集
'charset' => 'utf8',
];
数据库连接
./config/connect.php
<?php
namespace pdo_edu;
use PDO;
$dbConfig = require 'database.php';
// printf('<pre>%s</pre>',print_r($dbConfig,true));
extract($dbConfig);
echo $type,$host,$username.'<br>','dbname='.$dbname.'<br>';
$dsn = $type.':host='.$host.';dbname='.$dbname;
$db = new PDO($dsn, $username, $password);
// var_dump($db);
插入数据
./demo.php
<?php
// namespace pdo_edu;
// use PDO;
// /**
// * 1.读:select
// * 2.写:insert,update,delete
// * CURD:增删改查
// */
// /**
// * 1. 连接数据库。
// * 2. CURD
// * 3. 关闭连接。
// */
// // 1. 连接数据库
// $dsn = 'mysql:host=localhost;dbname=phpedu;port:3306;charset=utf8';
// $username = 'phpedu';
// $password = 'phpedu';
// $db = new PDO($dsn, $username, $password);
// var_dump($db);
// // 2. CURD
// // 3. 关闭连接
// // 销毁连接对象
// // $db = null;
// // unset($db);
////////////demo2////////////
namespace pdo_edu;
use PDO;
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// var_dump($db);
// 2. CURD
// INSERT INTO 表名 (字段名1,字段名2,字段名3...) VALUE (值1,值2,值3...)
// 简化:INSERT 表名 (字段名1,字段名2,字段名3...) VALUE (值1,值2,值3...)---少了INTO
// ------如果是mysql且插入单条,还可以简化------
// INSERT 表名 SET 字段名1=值1,字段名2=值2,字段名3=值3... 推荐尽可能使用
// SELECT * FROM `staff` WHERE 1
/**
* 1. SQL关键字推荐全部大写。
* 2. 表明,字段名必须用反引号,防止和关键字冲突。
*/
$sql = "INSERT `staff` SET `id` = 1, `name` = 'admin', `gender`=1, `email`='admin@php.cn'";
// 创建sql语句对象
$stmt = $db->prepare($sql);
var_dump($db);
var_dump($stmt);
if ($stmt->execute())
{
echo '插入成功!';
}else{
echo '插入不成功!';
// 获取错误码
echo $stmt->errorCode();
// 进一步获取错误信息
print_r ($stmt->errorInfo());
}