sethadam1 / pdofish
PHP和PDO的Active Record样式包装器
Requires
- php: >=7.2
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_at
和created_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 Carr的PDOWrapper项目。