ขอแนะนำอย่างยิ่งให้คุณใช้ flightphp/active-record แทนไลบรารีนี้ จะไม่มีการพัฒนาเพิ่มเติมกับไลบรารีนี้ แต่ยังคงใช้งานได้ตามปกติในขณะนี้
super model เป็นคลาส php ประเภท ORM ที่เรียบง่ายในการโต้ตอบกับตารางในฐานข้อมูลได้อย่างง่ายดายโดยไม่ต้องเขียนโค้ด SQL จำนวนมากทั่วสถานที่
เพื่อพิสูจน์ นี่คือบรรทัดของโค้ด...
$ cloc src/
1 text file.
1 unique file.
0 files ignored.
github.com/AlDanial/cloc v 1.74 T=0.01 s (71.8 files/s, 48768.5 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
PHP 1 86 246 347
-------------------------------------------------------------------------------
สิ่งนี้เขียนโดยคำนึงถึงประสิทธิภาพเป็นหลัก ดังนั้นถึงแม้ว่ามันจะไม่ตอบสนองทุกความต้องการในทุกโครงการที่เคยสร้างมา แต่มันก็ใช้งานได้ในกรณีส่วนใหญ่ และทำหน้าที่ได้ดีมากเช่นกัน!
การเริ่มต้นใช้งาน super model นั้นง่ายดาย เพียงขยายคลาส super model และกำหนดชื่อตาราง แค่นั้นแหละ.
<?php
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
}
แล้วตัวอย่างง่ายๆ เกี่ยวกับวิธีการทำงานของเธอล่ะ
ขั้นแรก สมมติว่าตารางต่อไปนี้:
Table: users
---------------------------------------------------------
| id | email | company_id |
| 1 | [email protected] | 50 |
| 2 | [email protected] | 61 |
| 3 | [email protected] | 61 |
---------------------------------------------------------
<?php
// somefile.php
$ pdo = new PDO ( ' sqlite::memory: ' , '' , '' , [ PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC ]);
$ User = new User ( $ pdo );
// WHERE company_id = 50
$ users = $ User -> getAllBycompany_id ( 50 );
// same as above
$ users = $ User -> getAll ([ ' company_id ' => 50 ]);
peasy ง่าย ๆ คั้นมะนาวใช่ไหม?
getBy*(mixed $value): array [result]
นี่คือวิธีการที่ส่งกลับหนึ่งแถวกลับจากค่าที่ระบุ ส่วน *
ของวิธีการอ้างถึงเขตข้อมูลในฐานข้อมูล ชื่อฟิลด์จะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ให้กับชื่อฟิลด์ของคุณที่อยู่ในตารางฐานข้อมูลของคุณ
// get by the id field on the users table
$ User -> getByid ( 3 );
/*
[
'id' => 3,
'email' => '[email protected]',
'company_id' => 61
]
*/
$ User -> getBycompany_id ( 61 );
/*
// it only will pull the first row, not all rows
[
'id' => 2,
'email' => '[email protected]',
'company_id' => 61
]
*/
getAllBy*(mixed $value): array [ [result], [result] ]
นี่คือตัวกรองทางลัดเพื่อส่งคืนแถวทั้งหมดตามค่าที่กำหนด ส่วน *
ของวิธีการอ้างถึงเขตข้อมูลในฐานข้อมูล ชื่อฟิลด์จะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ให้กับชื่อฟิลด์ของคุณที่อยู่ในตารางฐานข้อมูลของคุณ
// this is pointless, but will still work
$ User -> getAllByid ( 3 );
/*
[
[
'id' => 3,
'email' => '[email protected]',
'company_id' => 61
]
]
*/
$ User -> getAllBycompany_id ( 61 );
/*
[
[
'id' => 2,
'email' => '[email protected]',
'company_id' => 61
],
[
'id' => 3,
'email' => '[email protected]',
'company_id' => 61
]
]
*/
getAll(array $filters, bool $return_one_row = false): array [ [result], [result] ] or [result]
นี่คือตัวกรองที่คุณสามารถเพิ่มการปรับแต่งมากมายเพื่อกรองข้อมูลจากตารางของคุณ มีคีย์เฉพาะบางประการที่ควรทราบและโอเปอเรเตอร์บางตัวที่จะช่วยคุณดึงข้อมูลเฉพาะของคุณ
// Full example
$ filters = [
//
// arguments in the WHERE statement
//
' some_field ' => 5 , // some_field = ?
' some_field-= ' => 5 , // some_field = ?
' another_field ' => ' IS NULL ' , // some_field IS NULL
' another_field ' => ' IS NOT NULL ' , // some_field IS NOT NULL
' another_field-> ' => ' Apple ' , // another_field > ?
' another_field->= ' => ' Apple ' , // another_field >= ?
' another_field-< ' => ' Apple ' , // another_field < ?
' another_field-<= ' => ' Apple ' , // another_field <= ?
' another_field-!= ' => ' Apple ' , // another_field != ?
' another_field-<> ' => ' Apple ' , // another_field <> ?
' another_field-LIKE ' => ' Ap%ple ' , // another_field LIKE ?
' another_field-NOT LIKE ' => ' Apple% ' , // another_field NOT LIKE ?
' another_field-IN ' => [ ' Apple ' , ' Banana ' , ' Peach ' ], // another_field IN(??) double question mark gets parsed as array
' another_field-NOT IN ' => [ ' Apple ' , ' Banana ' , ' Peach ' ], // another_field NOT IN(??) double question mark gets parsed as array
// If you need some custom action
' another_field-RAW-> DATE_SUB(?, INTERVAL 1 DAY) ' => ' 1980-01-01 ' , // another_field > DATE_SUB(?, INTERVAL 1 DAY)
//
// Other parts of the query
//
// choose what columns you want to select
' select_fields ' => ' id, first_name ' ,
// Get any joins
' joins ' => [ ' LEFT JOIN companies ON companies.id = users.company_id ' ],
// Group by
' group_by ' => ' company_id ' ,
// having
' having ' => ' count > 5 ' ,
// order by
' order_by ' => ' id DESC ' ,
// limit
' limit ' => 15 ,
// offset
' offset ' => 10000 ,
];
$ users = $ User -> getAll ( $ filters );
นอกจากนี้ยังมีตัวเลือกการกำหนดค่าพื้นฐานพร้อมคุณสมบัติโมเดลอีกด้วย
หากคุณมีโมเดลที่คุณรู้ว่าจะส่งกลับชุดผลลัพธ์เล็กๆ เสมอ และต้องการให้สามารถสืบค้นทั้งตารางได้ ให้ตั้งค่าคุณสมบัตินี้ มิฉะนั้นจะเป็นการป้องกันถ้าไม่มีพารามิเตอร์ sql ส่งมา คุณจะไม่สามารถเรียกคืนชุดผลลัพธ์ทั้งหมดกลับคืนมาได้ (ซึ่งอาจเสียหายและทำให้หลายสิ่งหลายอย่างเสียหายได้)
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
protected $ disallow_wide_open_queries = false ;
}
create(array $data): int [insert id]
สิ่งนี้จะสร้างแถวเดียวบนตาราง แต่ถ้าคุณระบุอาร์เรย์หลายมิติ มันจะแทรกหลายแถว ถือว่าคีย์หลักของ id
$ User -> create ([ ' email ' => ' [email protected] ' , ' company_id ' => 55 ]);
// returns 4
$ User -> create ([ [ ' email ' => ' [email protected] ' , ' company_id ' => 55 ], [ ' email ' => ' [email protected] ' , ' company_id ' => 56 ] ]);
// returns 6, only the last id will be returned
update(array $data, string $update_field = 'id'): int (number of rows updated)
สิ่งนี้จะสร้างแถวเดียวบนตาราง แต่ถ้าคุณระบุอาร์เรย์หลายมิติ มันจะแทรกหลายแถว ถือว่าคีย์หลักของ id
$ User -> update ([ ' id ' => 1 , ' email ' => ' [email protected] ' ]);
// returns 1 and will only update the email field
$ User -> update ([ ' email ' => ' [email protected] ' , ' company_id ' => 61 ], ' email ' );
// returns 1
$ User -> update ([ ' company_id ' => 61 , ' email ' => ' [email protected] ' ], ' company_id ' );
// returns 3, not really logical, but it would update all the emails
จะเป็นอย่างไรถ้าคุณต้องการวิธีอัตโนมัติในการแก้ไขผลลัพธ์ของคุณหากมีการติดธงเฉพาะ เปย์ง่าย. มีเมธอดที่เรียกว่า processResult()
ที่จะเรียกใช้ทุกผลลัพธ์ที่คุณดึงกลับ คุณใส่ตัวกรองพิเศษสำหรับเมธอดนี้ในคีย์ $filters['processResults']
<?php
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
public processResult (array $ process_filters , array $ result ): array {
// add some trigger here and do whatever checks you need
if( isset ( $ process_filters ['set_full_name']) && $ process_filters ['set_full_name'] === true && !empty( $ result ['first_name']) && !empty( $ result ['last_name'])) {
$ result ['full_name'] = $ result [ ' first_name ' ]. ' ' . $ result [ ' last_name ' ];
}
return $ result ;
}
}
// later on in some other file.
$ User = new User ( $ pdo );
// setting the processResults filter here is the key to connecting the getAll statement with your processResult method
$ users = $ User -> getAll ([ ' company_id ' => 51 , ' processResults ' => [ ' set_full_name ' => true ] ]);
echo $ users [ 0 ][ ' full_name ' ]; // Bob Smith
จะเป็นอย่างไรถ้าคุณต้องการทำแบบสอบถาม SQL ที่ซับซ้อนซึ่งไม่อยู่ในขอบเขตของคลาสนี้หรือตัวกรอง getAll()
โปรดจำไว้ว่าจุดประสงค์ของชั้นเรียนนี้ ไม่ใช่ เพื่อตอบสนองทุกข้อกำหนดจากทุกโครงการที่เคยมีหรือจะมีอยู่ แต่จะช่วยให้คุณบรรลุเป้าหมายได้ 90% ด้วยเหตุนี้ จึงมีวิธีง่ายๆ ในการดำเนินการตามคำถามข้างต้น เพียงใช้ RAW SQL สำหรับการดำเนินการของคุณ
<?php
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
public function processCrazyKukooQuery ( /* add whatever required fields you need */ ): array {
$ db = $ this -> getDbConnection ();
// shamelessly ripped from StackOverflow
$ statement = $ db -> prepare ( " SELECT
DISTINCT
t.id,
t.tag,
c.title AS Category
FROM
tags2Articles t2a
INNER JOIN tags t ON t.id = t2a.idTag
INNER JOIN categories c ON t.tagCategory = c.id
INNER JOIN (
SELECT
a.id
FROM
articles AS a
JOIN tags2articles AS ta ON a.id=ta.idArticle
JOIN tags AS tsub ON ta.idTag=tsub.id
WHERE
tsub.id IN (12,13,16)
GROUP BY a.id
HAVING COUNT(DISTINCT tsub.id)=3
) asub ON t2a.idArticle = asub.id " );
$ statement -> execute ();
return $ statement -> fetchAll ();
}
}
เพียงรัน composer test
เพื่อรัน phpunit
และ phpstan
ขณะนี้ครอบคลุม 100% และนั่นคือสิ่งที่ฉันต้องการเก็บไว้
หมายเหตุเกี่ยวกับความครอบคลุม 100%: แม้ว่าโค้ดอาจมีความครอบคลุม 100% แต่ความครอบคลุม ที่แท้จริง นั้นแตกต่างออกไป เป้าหมายคือการทดสอบสถานการณ์ต่างๆ มากมายกับโค้ดเพื่อคิดโค้ดและคาดการณ์ผลลัพธ์ที่ไม่คาดคิด ฉันเขียนโค้ดให้ครอบคลุม "ของจริง" ไม่ใช่ครอบคลุม "โค้ดทำงาน"