(3)php框架开发---数据库模型开发
2017-10-04 22:12
218 查看
今天有空再写一篇php的数据库模型类开发,这次的数据库类采用的是pdo来实现的,因为pdo有较好的适用性,所以使用pdo比mysql,mysqli都要好用。
首先就是要确定基本的思路,首先要有一个模型类model.php,然后这个模型类有一个保护成员变量,这个变量用来保存数据库的对象,所以这里要使用一个数据库管理类db.php来规范管理所有的数据库对象,这些对象都保存在一个数据中,然后就可以非常的容易切换,之后就是各个数据库驱动mysql,mysqli等,这些驱动都要继承最基本的驱动类dirver.php这个驱动基本类。
基本的结构如下图:
数据库驱动文件类,这个类封装了基本的sql方法和变量,因为大多数的sql都使用到这些方法,所以做一个封装,然后让其它类继承。
driver类:
继承驱动类的mysqli类,这里可以写一些mysqli独有的方法,方便拓展开来
mysqli类:
db类其实就是用来全局静态的方法获取数据库实例对象,这样做的好处是,在使用同一个数据库对象的时候,我只要new一次就可以了。这里防止重复new相同的数据库,所以性能上是会有一定的提升。
db类:
直接提供操作数据库的接口方法。
model类:
这里面我的数据库driver里面没写人性化,因为query的时候没用给你绑定数据的参数传入。所以更改后应该是这样子的。
<?php
/**
* Created by PhpStorm.
* User: DMF
* Date: 2017/9/23
* Time: 15:59
*/
namespace core\database;
class driver
{
//数据库配置
protected $config = array(
'type' => 'mysql', // 数据库类型
'hostname' => '127.0.0.1', // 服务器地址
'database' => '123', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306', // 端口
'dsn' => 'mysql:host=localhost;dbname=automobileRepairStation', //pdo连接信息
);
//数据库pdo连接id 支持多个连接
protected $linkId = array();
//当前pdo连接id
protected $_linkId = null;
//pdo操作实例
protected $pdoStatement = null;
// 事务指令数
protected $transTimes = 0;
//当前sql指令
protected $querySql = '';
// 错误信息
protected $error = '';
//pdo连接参数
protected $options = array(
);
protected $bind = array(); // 参数绑定
//连接数据库函数
public function connect($config=array()){
if(empty($config)){
$config = $this->config;
}
try{
$this->_linkId = new \PDO($config['dsn'],$config['username'],$config['password']);
#echo "连接成功<br/>";
}catch (\PDOException $e) {
#echo $e->errorInfo(),$e->getMessage();
die ("Error!: " . $e->getMessage() . "<br/>");
}
return $this->_linkId;
}
//释放查询结果
public function free(){
$this->pdoStatement = null;
}
//启动事务
public function startTransaction(){
$this->connect();
if(!$this->_linkId)return false;
if($this->transTimes == 0){
$this->_linkId->beginTransaction();
}
$this->transTimes++;
}
//提交数据,要非自动提交
public function commit(){
if($this->transTimes>0){
$result = $this->_linkId->commit();
$this->transTimes = 0;
if(!$result){
$this->error();
return false;
}
}
return true;
}
//回滚数据
public function rollback(){
if($this->transTimes>0){
$result = $this->_linkId->rollback();
$this->transTimes = 0;
if(!$result){
$this->error();
return false;
}
}
return true;
}
//初始化连接
protected function initConnect(){
//判断是否存在连接对象
if(!$this->_linkId)$this->_linkId = $this->connect();
}
//关闭数据库
public function close(){
$this->_linkId = null;
}
//数据库错误信息
public function error(){
if($this->pdoStatement){
$error = $this->pdoStatement->errorInfo();
$this->error = $error[1].':'.$error[2];
}else{
$this->error = '';
}
return $this->error;
}
//析构函数
public function __destruct()
{
// TODO: Implement __destruct() method.
if($this->pdoStatement){
$this->free();
}
//关闭数据库连接
$this->close();
}
//执行查询,并返回结果集
public function query($sql,$fetchSql=false){
#echo '<br/>'.$sql.'<br/>';
$this->initConnect();
//判断是否初始化失败
if(!$this->_linkId)return fasle;
try{
//pdo执行sql语句准备
$this->pdoStatement = $this->_linkId->prepare($sql);
}catch (\PDOException $e) {
echo $e->getMessage();
return false;
}
return $this;
}
/*
* 数据绑定
* $name:名
* $value:值
*/
public function bindParam($name,$value){
$this->bind[':'.$name] = $value;
}
/*
* 数据绑定
* $params:键值对参数数组
*/
public function bind($params=null){
if(is_array($params)){
foreach($params as $k=>$v){
$this->bindParam($k,$v);
}
}
return $this;
}
/*
* 执行并返回数据
*/
public function fetch(){
if(!empty($this->bind)){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
}
//执行完成清空绑定数据数组
$this->bind = array();
//执行sql语句
$this->pdoStatement->execute();
//返回sql执行结果集
return $this->pdoStatement->fetch(\PDO::FETCH_ASSOC);
}
/*
* 执行并返回数据集
*/
public function fetchAll(){
if(!empty($this->bind)){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
}
//执行完成清空绑定数据数组
$this->bind = array();
//执行sql语句
$this->pdoStatement->execute();
//返回sql执行结果集
return $this->pdoStatement->fetchAll(\PDO::FETCH_ASSOC);
}
//执行查询
public function execute(){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
//执行sql语句
$flag = $this->pdoStatement->execute();
//执行完成清空绑定数据数组
$this->bind = array();
if($flag){
return true;
}
return false;
}
/*
* 插入数据
* $table:数据表
* $data:插入数据
*/
public function insert($table='',$data=array()){
if(empty($data)){
die('数据不能为空!');
}
//字段名处理
foreach($data as $k=>$v){
$fields[] = $k;
$values[] = $v;
$this->bindParam($k,$v);
}
//insert的sql语句处理
$sql = 'INSERT INTO '.$table.' ( '.implode(',',$fields)
.') VALUES (';
foreach($fields as $k=>$v){
$sql.=':'.$v.',';
}
$sql = rtrim($sql,',');
$sql .= ')';
echo '<br/>'.$sql.'<br/>';
return $this->execute($sql);
}
/*
* 删除数据
* $table:表名
* $data:插入数据
*/
public function delete($table='',$id=''){
$sql = 'DELETE FROM '.$table.' WHERE id='.$id;
echo $sql.'<br/>';
return $this->execute($sql);
}
/*
* 修改数据
* $table:表名
* $data:插入数据
*/
public function update($table='',$data=array()){
if(empty($data)){
die('数据不能为空!');
}
$sql = 'UPDATE '.$table.' SET ';
//字段名处理
foreach($data as $k=>$v) {
$sql = $sql.$k.'=:'.$k.',';
$this->bindParam($k,$v);
}
$sql = rtrim($sql,',');
$sql = $sql.' WHERE id='.$data['id'];
#echo $sql.'<br/>';
return $this->execute($sql);
}
/*
* 查询数据
* $table:表名
* $data:插入数据
*/
public function select($table='',$option=array()){
$sql = 'SELECT * FROM '.$table.' WHERE ';
foreach($option as $k=>$v){
$sql .= $k.'=:'.$k .' AND ';
}
$sql = rtrim($sql,' AND ');
echo $sql.'<br/>';
foreach($option as $k=>$v) {
$this->bindParam($k,$v);
}
return $this->query($sql);
}
}
仔细观察的话,我是将里面的方法细化了,加多了bind方法,fetch方法,fetchAll方法,execute方法。这样子就能够将query方法获取到pdoStatement,后再绑定数据到全局变量bind里面,然后再执行返回什么方法的结果集。
在使用bind的方法中,肯定会使用到bindParam的方法,这里面存在一个坑点,那就是bindParam(键,&值)的形式来进行绑定值的,所以当你使用foreach($values as $k=>$v)的时候,就会出现一直都是引用$v这个变量的值,所以一直都是最后面的获取到的值。所以这里要采用foreach($values as $k=>&$v)或是binValue这个函数。
首先就是要确定基本的思路,首先要有一个模型类model.php,然后这个模型类有一个保护成员变量,这个变量用来保存数据库的对象,所以这里要使用一个数据库管理类db.php来规范管理所有的数据库对象,这些对象都保存在一个数据中,然后就可以非常的容易切换,之后就是各个数据库驱动mysql,mysqli等,这些驱动都要继承最基本的驱动类dirver.php这个驱动基本类。
基本的结构如下图:
数据库驱动文件类,这个类封装了基本的sql方法和变量,因为大多数的sql都使用到这些方法,所以做一个封装,然后让其它类继承。
driver类:
<?php /** * Created by PhpStorm. * User: DMF * Date: 2017/9/23 * Time: 15:59 */ namespace Dphp\core\database; class driver { //数据库配置 protected $config = array( 'type' => 'mysql', // 数据库类型 'hostname' => '127.0.0.1', // 服务器地址 'database' => 'test', // 数据库名 'username' => 'root', // 用户名 'password' => 'root', // 密码 'hostport' => '8081', // 端口 'dsn' => 'mysql:host=localhost;dbname=test', //pdo连接信息 ); //数据库pdo连接id 支持多个连接 protected $linkId = array(); //当前pdo连接id protected $_linkId = null; //pdo操作实例 protected $pdoStatement = null; // 事务指令数 protected $transTimes = 0; //当前sql指令 protected $querySql = ''; // 错误信息 protected $error = ''; //pdo连接参数 protected $options = array( ); protected $bind = array(); // 参数绑定 //连接数据库函数 public function connect($config=array()){ if(empty($config)){ $config = $this->config; } try{ $this->_linkId = new \PDO($config['dsn'],$config['username'],$config['password']); echo "连接成功<br/>"; }catch (\PDOException $e) { echo $e->errorInfo(),$e->getMessage(); die ("Error!: " . $e->getMessage() . "<br/>"); } return $this->_linkId; } //释放查询结果 public function free(){ $this->pdoStatement = null; } //执行查询,并返回结果集 public function query($sql,$fetchSql=false){ echo '<br/>'.$sql.'<br/>'; $this->initConnect(); //判断是否初始化失败 if(!$this->_linkId)return fasle; try{ //pdo执行sql语句准备 $this->pdoStatement = $this->_linkId->prepare($sql); }catch (\PDOException $e) { echo $e->getMessage(); return false; } if($this->pdoStatement === false){ return false; } //数据绑定 foreach($this->bind as $k=>$v){ $this->pdoStatement->bindParam($k,$v); } //执行完成清空绑定数据数组 $this->bind = array(); //执行sql语句 $this->pdoStatement->execute(); //返回sql执行结果集 return $this->pdoStatement->fetchAll(\PDO::FETCH_ASSOC); } //执行查询,并返回结果集 public function execute($sql,$fetchSql=false){ echo '<br/>'.$sql.'<br/>'; $this->initConnect(); //判断是否初始化失败 if(!$this->_linkId)return fasle; try{ //pdo执行sql语句准备 $this->pdoStatement = $this->_linkId->prepare($sql); }catch (\PDOException $e) { echo $e->getMessage(); return false; } if($this->pdoStatement === false){ return false; } //数据绑定 foreach($this->bind as $k=>$v){ $this->pdoStatement->bindParam($k,$v); } //执行完成清空绑定数据数组 $this->bind = array(); //执行sql语句 return $this->pdoStatement->execute(); //var_dump($this->pdoStatement->errorInfo()); } //启动事务 public function startTransaction(){ $this->connect(); if(!$this->_linkId)return false; if($this->transTimes == 0){ $this->_linkId->beginTransaction(); } $this->transTimes++; } //提交数据,要非自动提交 public function commit(){ if($this->transTimes>0){ $result = $this->_linkId->commit(); $this->transTimes = 0; if(!$result){ $this->error(); return false; } } return true; } //回滚数据 public function rollback(){ if($this->transTimes>0){ $result = $this->_linkId->rollback(); $this->transTimes = 0; if(!$result){ $this->error(); return false; } } return true; } //初始化连接 protected function initConnect(){ //判断是否存在连接对象 if(!$this->_linkId)$this->_linkId = $this->connect(); } //关闭数据库 public function close(){ $this->_linkId = null; } //数据库错误信息 public function error(){ if($this->pdoStatement){ $error = $this->pdoStatement->errorInfo(); $this->error = $error[1].':'.$error[2]; }else{ $this->error = ''; } return $this->error; } //析构函数 public function __destruct() { // TODO: Implement __destruct() method. if($this->pdoStatement){ $this->free(); } //关闭数据库连接 $this->close(); } /* * 数据绑定 * $name:名 * $value:值 */ public function bindParam($name,$value){ $this->bind[':'.$name] = $value; } /* * 插入数据 * $table:数据表 * $data:插入数据 */ public function insert($table='',$data=array()){ if(empty($data)){ die('数据不能为空!'); } //字段名处理 foreach($data as $k=>$v){ $fields[] = $k; $values[] = $v; $this->bindParam($k,$v); } //insert的sql语句处理 $sql = 'INSERT INTO '.$table.' ( '.implode(',',$fields) .') VALUES ('; foreach($fields as $k=>$v){ $sql.=':'.$v.','; } $sql = rtrim($sql,','); $sql .= ')'; echo '<br/>'.$sql.'<br/>'; return $this->execute($sql); } /* * 删除数据 * $table:表名 * $data:插入数据 */ public function delete($table='',$id=''){ $sql = 'DELETE FROM '.$table.' WHERE id='.$id; echo $sql.'<br/>'; return $this->execute($sql); } /* * 修改数据 * $table:表名 * $data:插入数据 */ public function update($table='',$data=array()){ if(empty($data)){ die('数据不能为空!'); } $sql = 'UPDATE '.$table.' SET '; //字段名处理 foreach($data as $k=>$v) { $sql = $sql.$k.'=:'.$k.','; $this->bindParam($k,$v); } $sql = rtrim($sql,','); $sql = $sql.' WHERE id='.$data['id']; #echo $sql.'<br/>'; return $this->execute($sql); } /* * 查询数据 * $table:表名 * $data:插入数据 */ public function select($table='',$option=array()){ $sql = 'SELECT * FROM '.$table.' WHERE '; foreach($option as $k=>$v){ $sql .= $k.'=:'.$k .' AND '; } $sql = rtrim($sql,' AND '); echo $sql.'<br/>'; foreach($option as $k=>$v) { $this->bindParam($k,$v); } return $this->query($sql); } }
继承驱动类的mysqli类,这里可以写一些mysqli独有的方法,方便拓展开来
mysqli类:
<?php /** * Created by PhpStorm. * User: DMF * Date: 2017/9/23 * Time: 17:12 */ namespace Dphp\core\database\sqlDriver; class mysqli extends \Dphp\core\database\driver { }
db类其实就是用来全局静态的方法获取数据库实例对象,这样做的好处是,在使用同一个数据库对象的时候,我只要new一次就可以了。这里防止重复new相同的数据库,所以性能上是会有一定的提升。
db类:
<?php /** * Created by PhpStorm. * User: DMF * Date: 2017/9/23 * Time: 15:55 */ namespace Dphp\core; class db { static private $instance = array(); //数据库连接实例 static private $_instance = null; //当前数据库实例 //获取数据库实例 static public function getInstance($config=array()){ $md5 = md5(serialize($config)); //判断是否存在数据库实例对象 if(!isset(self::$instance[$md5])){ $class = 'Dphp\\core\\database\\sqlDriver\\mysqli'; self::$instance[$md5] = new $class(); echo 'new了一个数据库对象<br/>'; } else { echo '缓存一个数据库对象<br/>'; } return self::$instance[$md5]; } }
直接提供操作数据库的接口方法。
model类:
<?php /** * Created by PhpStorm. * User: DMF * Date: 2017/9/25 * Time: 13:12 */ namespace Dphp\core; class model { //数据库对象 protected $db; //初始化数据库对象 public function __construct($name='') { $this->db(); } //数据库对象实例化 public function db(){ if($this->db)return $this->db; //获取数据库对象 $this->db = \Dphp\core\db::getInstance(); return $this->db; } /* * 数据添加 * $table:表名 * $data:添加的数据 */ public function add($table='',$data=array()){ if(empty($table)||empty($data)){ die('数据表为空或数据为空'); } return $this->db->insert($table,$data); //var_dump($data2); } /* * 数据更新 * $table:表名 * $data:添加的数据 */ public function update($table='',$data=array()){ if(empty($table)||empty($data)){ die('数据表为空或数据为空'); } return $this->db->update($table,$data); //var_dump($data2); } /* * 数据删除 * $table:表名 * $data:添加的数据 */ public function delete($table='',$id=null){ if(empty($table)||empty($id)){ die('数据表为空或数据为空'); } return $this->db->delete($table,$id); //var_dump($data2); } /* * 数据查找 * $table:表名 * $data:添加的数据 */ public function select($table='',$option=array()){ if(empty($table)||empty($option)){ die('数据表为空或数据为空'); } return $this->db->select($table,$option); //var_dump($data2); } }
2017.10.31
在上面的数据库写法上,其实存在着一个bug和不方便的地方。这里面我的数据库driver里面没写人性化,因为query的时候没用给你绑定数据的参数传入。所以更改后应该是这样子的。
<?php
/**
* Created by PhpStorm.
* User: DMF
* Date: 2017/9/23
* Time: 15:59
*/
namespace core\database;
class driver
{
//数据库配置
protected $config = array(
'type' => 'mysql', // 数据库类型
'hostname' => '127.0.0.1', // 服务器地址
'database' => '123', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306', // 端口
'dsn' => 'mysql:host=localhost;dbname=automobileRepairStation', //pdo连接信息
);
//数据库pdo连接id 支持多个连接
protected $linkId = array();
//当前pdo连接id
protected $_linkId = null;
//pdo操作实例
protected $pdoStatement = null;
// 事务指令数
protected $transTimes = 0;
//当前sql指令
protected $querySql = '';
// 错误信息
protected $error = '';
//pdo连接参数
protected $options = array(
);
protected $bind = array(); // 参数绑定
//连接数据库函数
public function connect($config=array()){
if(empty($config)){
$config = $this->config;
}
try{
$this->_linkId = new \PDO($config['dsn'],$config['username'],$config['password']);
#echo "连接成功<br/>";
}catch (\PDOException $e) {
#echo $e->errorInfo(),$e->getMessage();
die ("Error!: " . $e->getMessage() . "<br/>");
}
return $this->_linkId;
}
//释放查询结果
public function free(){
$this->pdoStatement = null;
}
//启动事务
public function startTransaction(){
$this->connect();
if(!$this->_linkId)return false;
if($this->transTimes == 0){
$this->_linkId->beginTransaction();
}
$this->transTimes++;
}
//提交数据,要非自动提交
public function commit(){
if($this->transTimes>0){
$result = $this->_linkId->commit();
$this->transTimes = 0;
if(!$result){
$this->error();
return false;
}
}
return true;
}
//回滚数据
public function rollback(){
if($this->transTimes>0){
$result = $this->_linkId->rollback();
$this->transTimes = 0;
if(!$result){
$this->error();
return false;
}
}
return true;
}
//初始化连接
protected function initConnect(){
//判断是否存在连接对象
if(!$this->_linkId)$this->_linkId = $this->connect();
}
//关闭数据库
public function close(){
$this->_linkId = null;
}
//数据库错误信息
public function error(){
if($this->pdoStatement){
$error = $this->pdoStatement->errorInfo();
$this->error = $error[1].':'.$error[2];
}else{
$this->error = '';
}
return $this->error;
}
//析构函数
public function __destruct()
{
// TODO: Implement __destruct() method.
if($this->pdoStatement){
$this->free();
}
//关闭数据库连接
$this->close();
}
//执行查询,并返回结果集
public function query($sql,$fetchSql=false){
#echo '<br/>'.$sql.'<br/>';
$this->initConnect();
//判断是否初始化失败
if(!$this->_linkId)return fasle;
try{
//pdo执行sql语句准备
$this->pdoStatement = $this->_linkId->prepare($sql);
}catch (\PDOException $e) {
echo $e->getMessage();
return false;
}
return $this;
}
/*
* 数据绑定
* $name:名
* $value:值
*/
public function bindParam($name,$value){
$this->bind[':'.$name] = $value;
}
/*
* 数据绑定
* $params:键值对参数数组
*/
public function bind($params=null){
if(is_array($params)){
foreach($params as $k=>$v){
$this->bindParam($k,$v);
}
}
return $this;
}
/*
* 执行并返回数据
*/
public function fetch(){
if(!empty($this->bind)){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
}
//执行完成清空绑定数据数组
$this->bind = array();
//执行sql语句
$this->pdoStatement->execute();
//返回sql执行结果集
return $this->pdoStatement->fetch(\PDO::FETCH_ASSOC);
}
/*
* 执行并返回数据集
*/
public function fetchAll(){
if(!empty($this->bind)){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
}
//执行完成清空绑定数据数组
$this->bind = array();
//执行sql语句
$this->pdoStatement->execute();
//返回sql执行结果集
return $this->pdoStatement->fetchAll(\PDO::FETCH_ASSOC);
}
//执行查询
public function execute(){
//数据绑定
foreach($this->bind as $k=>&$v){
$this->pdoStatement->bindParam($k,$v);
}
//执行sql语句
$flag = $this->pdoStatement->execute();
//执行完成清空绑定数据数组
$this->bind = array();
if($flag){
return true;
}
return false;
}
/*
* 插入数据
* $table:数据表
* $data:插入数据
*/
public function insert($table='',$data=array()){
if(empty($data)){
die('数据不能为空!');
}
//字段名处理
foreach($data as $k=>$v){
$fields[] = $k;
$values[] = $v;
$this->bindParam($k,$v);
}
//insert的sql语句处理
$sql = 'INSERT INTO '.$table.' ( '.implode(',',$fields)
.') VALUES (';
foreach($fields as $k=>$v){
$sql.=':'.$v.',';
}
$sql = rtrim($sql,',');
$sql .= ')';
echo '<br/>'.$sql.'<br/>';
return $this->execute($sql);
}
/*
* 删除数据
* $table:表名
* $data:插入数据
*/
public function delete($table='',$id=''){
$sql = 'DELETE FROM '.$table.' WHERE id='.$id;
echo $sql.'<br/>';
return $this->execute($sql);
}
/*
* 修改数据
* $table:表名
* $data:插入数据
*/
public function update($table='',$data=array()){
if(empty($data)){
die('数据不能为空!');
}
$sql = 'UPDATE '.$table.' SET ';
//字段名处理
foreach($data as $k=>$v) {
$sql = $sql.$k.'=:'.$k.',';
$this->bindParam($k,$v);
}
$sql = rtrim($sql,',');
$sql = $sql.' WHERE id='.$data['id'];
#echo $sql.'<br/>';
return $this->execute($sql);
}
/*
* 查询数据
* $table:表名
* $data:插入数据
*/
public function select($table='',$option=array()){
$sql = 'SELECT * FROM '.$table.' WHERE ';
foreach($option as $k=>$v){
$sql .= $k.'=:'.$k .' AND ';
}
$sql = rtrim($sql,' AND ');
echo $sql.'<br/>';
foreach($option as $k=>$v) {
$this->bindParam($k,$v);
}
return $this->query($sql);
}
}
仔细观察的话,我是将里面的方法细化了,加多了bind方法,fetch方法,fetchAll方法,execute方法。这样子就能够将query方法获取到pdoStatement,后再绑定数据到全局变量bind里面,然后再执行返回什么方法的结果集。
在使用bind的方法中,肯定会使用到bindParam的方法,这里面存在一个坑点,那就是bindParam(键,&值)的形式来进行绑定值的,所以当你使用foreach($values as $k=>$v)的时候,就会出现一直都是引用$v这个变量的值,所以一直都是最后面的获取到的值。所以这里要采用foreach($values as $k=>&$v)或是binValue这个函数。
相关文章推荐
- 什么时候开发人员需要PHP框架
- CoolBlog开发笔记第4课:数据库模型设计
- 超简单开发自己的php框架一点都不难!!
- PhpBoot: 一款用于快速开发 RESTful 接口的PHP框架
- TOME开发框架1.0.0(PHP框架)
- 3个最好的PHP框架的Web开发
- [存档]php框架、集成开发环境
- fleaphp 快速开发php框架
- 构建快速开发web项目的php框架 完成楼盘微信小程序后台
- C开发的PHP框架Phalcon性能有多高
- PHP框架之ThinkPHP项目CMS内容管理系统源码及开发手册视频
- PHP框架开发一(首言)
- Web开发之PHP框架(二)-Laravel数据库初步及MVC
- 高性能PHP框架thinkphp5.0.0 Beta发布-为API开发而设计
- 易于开发Web 2.0应用程序的5个PHP框架
- 想要开发自己的PHP框架需要那些知识储备?
- 求php框架开发视频教程
- 11个PHP框架——Web开发人员最爱
- 打算把这里做为我的PHP框架开发基地
- 开发人员最常用的的13款PHP框架