sethadam1/pdofish

该软件包最新版本(dev-main)没有可用的许可证信息。

PHP和PDO的Active Record样式包装器

dev-main 2023-05-08 18:12 UTC

This package is auto-updated.

Last update: 2024-09-08 20:51:22 UTC


README

PHP和PDO的Active Record样式包装器

目的

PHP Active Record的最后一个稳定版本发布于2010年,最新夜间版本发布于2013年。由于PHPAR似乎已被放弃,但仍在许多项目中使用,因此PdoFish被设计为一个极轻量级的Active Record语法子集的替代品。目标是创建PHPAR的某些但不是全部约定的替换品。

本项目的目标是重新创建与表模型一起工作的静态方法。本项目并不适合所有人。马虎的编程可能会破坏这些功能。然而,如果您已经在使用PHPAR或希望在PHP中使用Active Record风格的数据库接口,这可能适合您。明确地说,PHPAR中的许多约定在PdoFish中都没有实现,但本项目的目标是创建尽可能薄的PDO层上的简单、易读的代码。

当前支持的方法

Model::raw() - 执行原始SQL
Model::find_by_pk() - 通过主键查找单行
Model::find() - 通过名为"id"的列查找
Model::all() - 返回与查询匹配的所有行
Model::first() - 返回与查询匹配的第一行
Model::last() - 返回与查询匹配的第一行
Model::find_by_sql() - 返回与查询匹配的单行
Model::find_all_by_sql() - 返回与查询匹配的所有行
Model::lastInsertId() - 返回最后插入ID
Model::count() - 返回匹配行数
Model::save() - 插入/创建/保存数据
Model::insert() - 插入记录
Model::update() - 更新字段
Model::delete() - 删除行
Model::delete_by_id() - 通过名为"id"的列删除
Model::delete_all() - 通过提供的条件删除
Model::deleteMany() - 删除多个匹配条件的行
Model::set_fetch_mode() - 设置PDO获取模式,例如PDO::FETCH_OBJ或PDO::FETCH_ASSOC

动态函数名称

Model::find_by_[field] - 通过特定列值查找单行
Model::find_all_by_[field] - 查找匹配给定值的单列的多个行

以下方法必须通过PdoFish类调用

PdoFish::load_models($path) - 加载PdoFish模型。这可以通过实例化或通过此显式函数完成
PdoFish::truncate($table) - 截断表,必须通过PdoFish类调用

以下方法也得到支持

PdoFish::connection()->query($sql) 将通过PDO的query()接口执行原始SQL语句
PdoFish::table()->last_sql 将返回通过PdoFish运行的最后SQL查询 - 它不是针对特定模型的。请注意,它不会捕获通过PdoFish::connection()运行的SQL。

不支持的内容

相当多,但希望不是您需要的约定。以下是在PdoFish中尚未实现的已知的PHPAR功能的列表

  • 多个活动连接(将在未来的版本中提供)
  • 外键关系
  • 事务,包括回滚
  • 预加载
  • 验证
  • 关联
  • 委托者
  • 属性设置器
  • 别名
  • 序列化
  • 自动时间戳
  • find()函数传入数组
  • first()函数传入值数组,例如:ModelName::first(array(2,3));
  • 只读模型
  • 回调函数 - 之前回调和之后回调
  • 关联,例如$has_many$belongs_to(如果设置在模型中,这些属性将被安全忽略)
  • Model::table()->xxx属性(除了last_sql
  • updated_atcreated_at字段的自动时间戳
  • 将数组传入查找数组参数的joins元素。 joins应为一个字符串。有关更多信息,请参阅支持的参数

安装

您可以使用Composer或手动安装PdoFish。

使用Composer

composer require sethadam1/pdofish

手动

  • 将文件上传到您的网络服务器。
  • 在您的models/目录(或任何其他目录)中添加任何模型,确保使用示例来扩展PdoFish类并设置$table变量和id,如果您的主键尚未命名为id
  • 在您的代码中包含Pdofish/PdoFish.php,您应该可以开始使用了。
require_once '/path/to/PdoFish/PdoFish.php';  

基本CRUD

要向表中插入数据,您可以使用Active Record风格的语法。这两种语法都是有效的

创建

$data = [
	'id' => 1,  
	'col1' => '2020-08-27 09:58:01',  
	'col2'=> 'a string',  
	'col3' => 12345  
];  
$y = new ModelName($data);  
$y->save();  
  
$x = new ModelName();  
$x->id = 1;  
$x->col1 = '2020-08-27 09:58:01';  
$x->col2 = 'a string';  
$x->col3 = "12345";  
$x->save();  

类似于PHP Active Record,->save()方法可用于更新现有对象或插入新对象。但是,如果主键不是名为“id”,您需要确保在模型上设置了一个主键。如果不指定该情况下的主键,则更新将失败,并且它将尝试插入新行。

非PHPAR的插入方式如下

$data = [
	'id' => 1,  
	'col1' => '2020-08-27 09:58:01',  
	'col2'=> 'a string',  
	'col3' => 12345  
];   
$insertid = ModelName::insert($data);    
  
echo $insertid;   
// example response "3"  

读取

PHPAR支持几种读取数据的方式。

//both of these print an object
$x = ModelName::first(['conditions'=>['some_field=?', 'some_value']]);
print_r($x); 

$x = ModelName::last(['conditions'=>['some_field=?', 'some_value']]);
print_r($x); 
//prints an associative array 
$x = ModelName::first(['conditions'=>['some_field=?', 'some_value']], PDO::FETCH_ASSOC);
print_r($x); 
//also prints an associative array   
ModelName::set_fetch_mode(PDO::FETCH_ASSOC); 
$x = ModelName::first(['conditions'=>['some_field=?', 'some_value']]);
print_r($x); 
// print a row where primary key, in this case 'example_id' = 5
$x = ModelName::find_by_pk(5);
print_r($x);
// print a single row matching SQL query  
$x = ModelName::find_by_sql('select * from random_table where random_field=12');
print_r($x);
// print a row where id = 5   
$x = ModelName::find(5);
print_r($x); 
// print 5 rows of data from this query   
$x = ModelName::all([
	'select'=>'field1, field2, field3',
	'from'=>'table t',
	'joins'=>'LEFT JOIN table2 t2 ON t.field1=t2.other_field',
	'conditions' => ['some_field=?', 'some_value'],
	'order'=>'field3 ASC',
	'limit'=>5
], PDO::FETCH_OBJ);
print_r($x);

以下PHPAR样式受支持,但建议不要使用

// print a row where name is "John"   
$x = ModelName::find('first' array('conditions'=>array('name=?','John')));
print_r($x); 
// print all rows where user_id is greater than 1   
$x = ModelName::find('all' array('conditions'=>array('id>?','1')));
print_r($x); 

更新

// updates column "firstname" to "Boris" where id = 5
ModeName::update(['firstname'=>'Boris'], ['id'=>5]); 

// updates columns "firstname" to "June", "lastname" to "Basoon" where id = 5
ModeName::update(['firstname'=>'June', 'lastname'=>'Basoon'], ['id'=>5]); 

您可以使用现有模型对象上的save()方法,就像在Active Record中一样,前提是它有一个名为"id"的属性,该属性与表中的唯一列匹配,或者模型中定义了$primary_key属性。

考虑一个有三个列的表,“id”,“columnA”和“columnB”。

// this will work if ModelName has a pk of "id" or has a $primary_key defined. 
$y = ModelName::find(3); //find a model with primary key=3  
$y->columnA = "Updated field!";  
$y->save(); // this will work   

现在考虑一个有三个列的表,“row_id”,“columnA”和“columnB”。

// this will also work  
$y = ModelName::find(3); //find a model with primary key=3  
$y->columnA = "Updated field!";  
$y->save(); // this will work only if the next lines are also configured...   

但是ModelName必须定义正确的属性,如下所示

class ModelName extends PdoFish {
	static $table_name = 'tablename';
	static $primary_key = 'row_id';
}

删除

// delete rows where column "firstname" is equal to "Boris"  
ModeName::delete(['firstname'=>'Boris']);   
  
// delete row where column "id" is equal to "5"  
ModeName::delete_by_id(5);   
  
// delete rows where column "user_id" is equal to 1, 2, or 3  
ModeName::deleteMany(['user_id', '1,2,3']);   

// delete via criteria, e.g. rows where column "user_id" is equal to 1, 2, or 3  
ModeName::delete_all([ 'conditions'=>['user_id=? OR user_id=? OR user_id=?',1,2,3] ]);   
   
// this will truncate an entire table. You MUST call this via the PdoFish class, and not a child class  
PdoFish::truncate('tableName');  

// you cannot use table()->method() functions   
$y = ModelName::find(3); //find a model with primary key=3  
$y->delete(); // this will not work   

支持的参数

PdoFish查询中支持以下参数
select - 要选择的列
from - 表,或表和别名 例如 "prices p"
joins - 以SQL语法表示的连接字符串,例如 LEFT JOIN table2 on prices.field=table2.field。注意,您不能在这里使用数组。
conditions - 一个包含SQL的数组,使用?占位符和要绑定的参数 例如 ['year=? AND mood=?',2021,'happy']
group - 分组,使用字段名
having - having,例如 'count(x)>3'
order - 排序,_例如 'id DESC'
limit - 大于0的正整数

致谢

一些代码源于David CarrPDOWrapper项目。