Es wird dringend empfohlen, anstelle dieser Bibliothek „flightphp/active-record“ zu verwenden. Diese Bibliothek wird nicht weiter weiterentwickelt, sie funktioniert jedoch so, wie sie derzeit ist.
super model ist eine sehr einfache PHP-Klasse vom Typ ORM, mit der Sie problemlos mit Tabellen in einer Datenbank interagieren können, ohne eine Menge SQL-Code schreiben zu müssen.
Um es zu beweisen, hier sind die Codezeilen ...
$ 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
-------------------------------------------------------------------------------
Dies wurde unter Berücksichtigung der Leistung geschrieben. Auch wenn es also nicht alle Anforderungen in jedem Projekt erfüllt, das jemals gebaut wurde, wird es in den meisten Fällen funktionieren und dabei auch noch einen tollen Job machen!
Der Einstieg in super model ist einfach: Erweitern Sie einfach die super model Klasse und definieren Sie einen Tabellennamen. Das ist es auch schon.
<?php
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
}
Wie wäre es nun mit ein paar einfachen Beispielen dafür, wie sie funktioniert?
Nehmen wir zunächst die folgende Tabelle an:
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 ]);
Kinderleicht, Zitronensaft, oder?
getBy*(mixed $value): array [result]
Dies ist eine Methode, die vom angegebenen Wert eine Zeile zurückgibt. Der *
-Teil der Methode bezieht sich auf ein Feld in der Datenbank. Beim Feldnamen wird die Groß-/Kleinschreibung beachtet, je nachdem, was auch immer Ihr Feldname in Ihrer Datenbanktabelle ist.
// 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] ]
Dies ist ein Shortcut-Filter, um alle Zeilen nach einem bestimmten Wert zurückzugeben. Der *
-Teil der Methode bezieht sich auf ein Feld in der Datenbank. Beim Feldnamen wird die Groß-/Kleinschreibung beachtet, je nachdem, was auch immer Ihr Feldname in Ihrer Datenbanktabelle ist.
// 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]
Dies ist der Filter, dem Sie eine Reihe von Anpassungen hinzufügen können, um die Daten aus Ihrer Tabelle zu filtern. Es gibt einige eindeutige Schlüssel, die Sie beachten sollten, und einige Operatoren, die Ihnen beim Abrufen Ihrer spezifischen Daten helfen.
// 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 );
Es gibt auch einige grundlegende Konfigurationsoptionen für die Modelleigenschaften.
Wenn Sie über ein Modell verfügen, von dem Sie wissen, dass es immer eine kleine Ergebnismenge zurückgibt, und Sie die gesamte Tabelle abfragen möchten, legen Sie diese Eigenschaft fest. Andernfalls handelt es sich um einen Schutz, sodass Sie, wenn keine SQL-Parameter angegeben würden, nicht die gesamte Ergebnismenge zurückholen würden (was zum Absturz führen und viele Dinge zerstören könnte).
use n0nag0n Super_Model ;
class User extends Super_Model {
protected $ table = ' users ' ;
protected $ disallow_wide_open_queries = false ;
}
create(array $data): int [insert id]
Dadurch wird eine einzelne Zeile in der Tabelle erstellt. Wenn Sie jedoch ein mehrdimensionales Array angeben, werden mehrere Zeilen eingefügt. Es wird ein Primärschlüssel mit der id
angenommen.
$ 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)
Dadurch wird eine einzelne Zeile in der Tabelle erstellt. Wenn Sie jedoch ein mehrdimensionales Array angeben, werden mehrere Zeilen eingefügt. Es wird ein Primärschlüssel mit der id
angenommen.
$ 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
Was ist, wenn Sie Ihr Ergebnis automatisch ändern möchten, wenn eine bestimmte Flagge ausgelöst wird? Kinderleicht. Es gibt eine Methode namens processResult()
, die jedes Ergebnis durchläuft, das Sie zurückziehen. Sie fügen spezielle Filter für diese Methode in den Schlüssel $filters['processResults']
ein.
<?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
Was ist, wenn Sie eine verrückt komplexe SQL-Abfrage durchführen müssen, die nicht in den Bereich dieser Klasse oder der getAll()
-Filter fällt?
Denken Sie daran, dass der Zweck dieses Kurses NICHT darin besteht, alle Anforderungen jedes Projekts zu erfüllen, das es jemals gab oder geben wird, sondern dass er Sie zu 90 % auf den Weg dorthin bringt. Vor diesem Hintergrund gibt es eine einfache Möglichkeit, die obige Frage auszuführen. Verwenden Sie einfach RAW SQL für Ihr Einzelstück.
<?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 ();
}
}
Führen Sie einfach composer test
aus, um phpunit
und phpstan
auszuführen. Derzeit liegt die Abdeckung bei 100 % und dort möchte ich sie auch behalten.
Ein Hinweis zur 100-prozentigen Abdeckung: Auch wenn der Code möglicherweise eine 100-prozentige Abdeckung aufweist, ist die tatsächliche Abdeckung anders. Das Ziel besteht darin, viele verschiedene Szenarien anhand des Codes zu testen, um den Code zu durchdenken und unerwartete Ergebnisse zu antizipieren. Ich codiere auf „echte“ Abdeckung, nicht auf „hat der Code ausgeführt“-Abdeckung.