It features a simple and fluent interface that can easily handle DB related tasks . It has an intentional no fuss setup with nearly zero configuration, so you can get up and running literally in a minute
- Makes simple queries and simple CRUD operations completely painless.
- Gets out of the way when more complex SQL is required.
- Built on top of PDO.
- Uses prepared statements throughout to protect against SQL injection attacks.
- Requires no model classes, no XML configuration and no code generation.
- Supports collections of models with method chaining to filter or apply actions to multiple results at once.
- Fast and Small footprint
The first thing in setting up Linda is editing the Linda.inc file, this file contains database connection parameters/constants. The file contains the following constants, edit to your needs
define('LINDA_DB_HOST', 'hostname');
define('LINDA_DB_TYPE', 'dbtype' );
define('LINDA_DB_NAME', 'dbname');
define('LINDA_DB_USER', 'user' );
define('LINDA_DB_PASSW', 'password' );
Autoload the LindaModel.php file or require/include it
Lets look at performing a select operation First create a LindaModel instance which accepts the table name as its constructor argument, the phpunit test files use the open source employee database dump files, available here Employee database
use solutionstack\Linda\LindaModel;
$l = new LindaModel("`employees");
$l->fetchAll(); //this retrieves all rows from the database and stores them in memory
The above fetches all rows and stors them as row-mapped objects in memory ready for access and updating
Each row returned is represented as an object with getter and setter features, as LindaModel implements an ActiveRecord interface
Once the records are avialable in memory we can retrieve them into variables
//using the #collection method, i can do..
$rows = $l->collection(); //returns collection of all row objects in an array, returns null if an empty set was returned from the DB
foreach($rows as $rows) echo $rows->address ."<br/>"; //this would print out the value of each address column
//now lets change the gender column on all rows to 'M'
foreach($rows as $rows)$rows->address = "New Address to Set";
After updating column values on a row object, its initially set only in Memory, you commit back into the table by calling the save method
$l->save(); //by now all address columns in the address table, would have been updated
Updates can alsobe performed on selected colums using the #set method
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees"); database
$l->where("emp_no", ">", 20000
->get()
->set([
'gender' => "M",
'last_name' => "Bar"
])
->save(); //updates the gender and last name columns for the retrieved rows
In the above say we didnt want to retrieve the entire row models into a variable with #collection
other methods exists including... first(), last(), even(), odd(), random();
They all return null if no results where retrieved from the table
$l->first(); //retuns the object model for first row of the collection
$l->last(); //retuns the object model for last row of the collection
$l->even(); //retuns the collection of even rows object models
$l->odd(); //retuns the collection of odd rows object models
$l->random(); //like #collection but the row models are sorted in a random order
$l->count(); //count all rows on the table (retrieved or not)
$l->numRows(); // indicating the number of rows retrieved or affected by the last operation
$l->hasErrors(); // if the last operation raised an Exception
$l->getLastError();//get the last error string if any
$l-> getLastQuery(); //get the last executed query
In the above examples we use #fetchAll() to first retrieve all rows of the table as objects in memory. This isnt what you do in most cases as data retrieval from tables are usually filtered by clauses like WHERE clauses, WHERE IN, JOINS etc, the LindaModel class provides for an increasing number of this clauses
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees"); database
$l->where("emp_no", ">", 20000); //this basically would apply an SQL where clause similar to ... WHERE(`emp_no` < 300)
After using a CLAUSE the #get method is used to retrieve the matched rows into memory, as opposed to #fetchAll which just loads in all the rows
so the full example for the where clause would be
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->where("emp_no", ">", 20000)
->get() //fetch rows into memory
->collection(); // get row objects that where fetched as a collection
The second parameter in a where method call takes any standard MySQL operator
- =
- >
- LIKE etc
Multiple calls to a #where method would get AND'ed togethere, as in the following example
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->where("emp_no", ">", 20000)
->where("gender","=", "F")
->get()
->collection();
The above would generate/execute the following SQL statement
SELECT * FROM `employees` WHERE( `emp_no` > 20000 ) AND ( `gender` = 'F' ) LIMIT 0, 1000;
To Compare WHERE clauses OR' wise use the #where_or method, this method ensures that the next CLAUSE is comopared OR' wise
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->where_or("emp_no", ">", 10001)
->where("emp_no", "<", 10010)
->get()
->collection();
SELECT * FROM `employees` WHERE( `emp_no` = 10011 ) OR ( `emp_no` = 10010 ) LIMIT 0, 1000;
Linda also supports where_in clauses
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->whereOr("emp_no", "=", 10011)
->whereIn("emp_no", [10010,10013,10024])
->get()
->collection();
would generate
SELECT * FROM `employees` WHERE( `emp_no` = 10011 ) AND `emp_no` IN (10010,10013,10024) LIMIT 0, 1000;
whereIn are compared AND'wise independent of whether one uses #whereOr previously (as seen above) To get whereIn to compare OR'wise use #whereInOr as the following example illustrates
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->where("emp_no", "=", 10011)
->whereInOr("emp_no", [10010,10013,10024])
->get()
->collection();
would execute the SQL statement...
SELECT * FROM `employees` WHERE( `emp_no` = 10011 ) OR `emp_no` IN (10010,10013,10024) LIMIT 0, 1000;
There are also complimentary #whereNotIn and #whereNotInOr methods. eg illustrates
use solutionstack\Linda\LindaModel;
$l = new LindaModel("employees");
$rows = $l->whereNotIn("emp_no", "select `emp_no` from `employees` where `emp_no` < 10010") //yes sub-queries are allowed
->get()
->collection();
Would generate the following SQL
SELECT * FROM `employees` WHERE `emp_no` NOT IN (select `emp_no` from `employees` where `emp_no` < 10010)
Linda automatically detects the PRIMARY_KEY on the table if one is avaialable. If not you'l need to specify what colum, to use as a key before updates would suceed. The key is specified as the second argument to the constructor only when a default PRI_KEY doesn't exists else it's ignored
$l = new LindaModel("address","unique_key_column_name");
Inner Joins are a common way to retrieve related data from multiple table and the LindaModel class provides a convinient method to perform such joins
The INNER JOIn method signature is
innerJoin($table, $conditional_column_a, $conditional_column_b)
where $table is the table you want to JOIN with.
$conditional_column_a is column on the current table you are operating on
$conditional_column_b is the column to match on the JOIN'ed table
Using the #innerJoin method
$l = new LindaModel("employees");
$rows = $l->innerJoin("salaries", "emp_no", "emp_no")
->whereIn("T1.emp_no", "select `emp_no` from `employees` where `emp_no` < 10010")
->get(["T2.salary"])
->collection();
SELECT T1.emp_no,T2.salary FROM `employees` AS T1 INNER JOIN `salaries` AS T2 ON T1.emp_no = T2.emp_no WHERE T1.emp_no IN (select `emp_no` from `employees` where `emp_no` < 10010) LIMIT 0, 1000;
It is important to note that joined table are aliased as T.x starting from T1 representing the main table. The above examplealso showcases an important feature where we can fetch only values from specific columns as seen in the #get method call. When fetching specific columns the PRIMARY_KEY is always fetchedalsong side custom columns
LindaModel supports two methods #take() and #skip() for paginating reslts
use solutionstack\Linda\LindaModel;
$l = new LindaModel("salaries");
$l->whereIn("salary", [60117, 603317, 30127])
->where("emp_no","<" ,10031)
->take(10)
->skip(4);
$rows = $l->get()->collection();
Would execute the Statement ```sql SELECT * FROM `salaries` WHERE ( `emp_no` < 10031 ) AND `salary` IN (60117,603317,30127) LIMIT 4, 10; ```
To insert new rows use the create method.
$l = new LindaModel("address");
$l->create(array(
["val1", "val2",...] //colum data for a row
)
);
$l = new LindaModel("address");
$l->create(array(
["val1", "val2",...],
["val1", "val2",...],
["val1", "val2",...])
);
$l = new LindaModel("address");
$l->create(array(
["val1", "val2"],
["val1", "val2"],
["val1", "val2"]
),['column1_name','column2_name']
);
To insert column data that takes a MySql DATE or DATETIME use the string NOW() or TIME()
$l = new LindaModel("address");
$l->create(["NOW()", "TIME()",...]);
To remove rows from the table after fetching the object models using either #fetchAll() or #get() simply call #remove() to delete those rows from a table
$l = new LindaModel("employees");
$rows = $l->where("emp_no", ">", 20000)
->get() //fetch rows into memory
->remove(); //remove rows from table
To ensure the returned result set/models contains unique, values for the columns, use #distinct
$l = new LindaModel("address");
$l->where("city_id","<" ,100) //wher the city_id is within that range)
->take(10)
->skip(4)
->distinct() //ensure rows column values are unique
->get(["address"]); //we are getting just this column data