Skip to content

grayphp/micro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHP Micro Framework

Think big, code small with Micro - the PHP micro framework for web applications.

Installation

Install via composer

 composer create-project grayphp/micro my-app
 cd my-app
php dev start
http://localhost:4000

Usage/Examples

Abailable Routes:

[get,post,patch,put,delete,any]

Route

use system\router\Route;
Route::get('/path',[controller::class,'method']);
Route::method('/path',callback);

Middleware

Route::any('/profile', ['controller' => HomeController::class, 'profile', 'middleware' => UserAuth::class]);

Dynamic Route

Route::get('/user/$id',function($id)){
    print $id;
}

controller

Make controller

php dev -c MyController

Middleware

Make Middleware

php dev -m MyMiddleware

Database

Your can access to Database using DB() helper.

Basic CRUD:

You can interact directly with the tables to insert/update/delete/select data:

Use ArrayAccess interface to access to the data using the id:

DB instance

$db = DB();
//Get the post id = 3;
$post = $db->post[3];
//Check if a row exists
if (isset($db->post[3])) {
    echo 'exists';
}
//Delete a post
unset($db->post[3]);
//Update a post
$db->post[3] = [
    'title' => 'Hello world'
];
//Insert a new post
$db->post[] = [
    'title' => 'Hello world 2'
];
//Tables implements the Countable interface
$totalPost = count($db->post);

Select by other fields

If you want to select a row by other key than id, just use the method get:

$post = $db->post->get(['slug' => 'post-slug']);

Select or create

Sometimes, you want to get a row or create it if it does not exist. You can do it easily with getOrCreate method:

$post = $db->post->getOrCreate(['slug' => 'post-slug']);

Rows

A Row object represents a database row and is used to read and modify its data:

//get a row by id
$post = $db->post[34];
//Get/modify fields values
echo $post->title;
$post->title = 'New title';
//Update the row into database
$post->save();
//Remove the row in the database
$post->delete();
//Create a new row
$newPost = $db->post->create(['title' => 'The title']);
//Insert the row in the database
$newPost->save();

Queries

A Query object represents a database query. SimpleCrud uses magic methods to create queries. For example $db->post->select() returns a new instance of a Select query in the tabe post. Other examples: $db->comment->update(), $db->category->delete(), etc... Each query has modifiers like orderBy(), limit():

//Create an UPDATE query with the table post
$updateQuery = $db->post->update(['title' => 'New title']);
//Add conditions, limit, etc
$updateQuery
    ->where('id = ', 23)
    ->limit(1);
//get the query as string
echo $updateQuery; //UPDATE `post` ...
//execute the query and returns a PDOStatement with the result
$PDOStatement = $updateQuery();

The method get() executes the query and returns the processed result of the query. For example, with insert() returns the id of the new row:

//insert a new post
$id = $db->post
    ->insert([
        'title' => 'My first post',
        'text' => 'This is the text of the post'
    ])
    ->get();
//Delete a post
$db->post
    ->delete()
    ->where('id = ', 23)
    ->get();
//Count all posts
$total = $db->post
    ->selectAggregate('COUNT')
    ->get();
//note: this is the same like count($db->post)
//Sum the ids of all posts
$total = $db->post
    ->selectAggregate('SUM', 'id')
    ->get();

select()->get() returns an instance of RowCollection with the result:

$posts = $db->post
    ->select()
    ->where('id > ', 10)
    ->orderBy('id ASC')
    ->limit(100)
    ->get();
foreach ($posts as $post) {
    echo $post->title;
}

If you only need the first row, use the modifier one():

$post = $db->post
    ->select()
    ->one()
    ->where('id = ', 23)
    ->get();
echo $post->title;

select() has some interesting modifiers like relatedWith() to add automatically the WHERE clauses needed to select data related with other row or rowCollection:

//Get the post id = 23
$post = $db->post[23];
//Select the category related with this post
$category = $db->category
    ->select()
    ->relatedWith($post)
    ->one()
    ->get();

Query API:

Queries use Atlas.Query library to build the final queries, so you can see the documentation for all available options.

Select / SelectAggregate

Function Description
one Select 1 result.
relatedWith(Row / RowCollection / Table $relation) To select rows related with other rows or tables (relation added in WHERE).
joinRelation(Table $table) To add a related table as LEFT JOIN.
getPageInfo() Returns the info of the pagination.
from Atlas.Query Select()
columns Atlas.Query Select()
join Atlas.Query Select()
catJoin Atlas.Query Select()
groupBy Atlas.Query Select()
having Atlas.Query Select()
orHaving Atlas.Query Select()
orderBy Atlas.Query Select()
catHaving Atlas.Query Select()
where Atlas.Query Select()
whereSprintf Atlas.Query Select()
catWhere Atlas.Query Select()
orWhere Atlas.Query Select()
orWhereSprintf Atlas.Query Select()
whereEquals Atlas.Query Select()
limit Atlas.Query Select()
offset Atlas.Query Select()
distinct Atlas.Query Select()
forUpdate Atlas.Query Select()
setFlag Atlas.Query Select()
bindValue Atlas.Query Select()

Update

Function Description
relatedWith(Row / RowCollection / Table $relation) To update rows related with other rows or tables (relation added in WHERE).
set Atlas.Query Update()
setFlag Atlas.Query Update()
where Atlas.Query Update()
orWhere Atlas.Query Update()
catWhere Atlas.Query Update()
orderBy Atlas.Query Update()
limit Atlas.Query Update()
offset Atlas.Query Update()

Insert

Function Description
orIgnore() To ignore silently the insertion on duplicated keys, instead throw an exception.
set Atlas.Query Insert()
setFlag Atlas.Query Insert()

Delete

Function Description
relatedWith(Row / RowCollection / Table $relation) To delete rows related with other rows or tables (relation added in WHERE).
setFlag Atlas.Query Delete()
where Atlas.Query Delete()
orWhere Atlas.Query Delete()
catWhere Atlas.Query Delete()
orderBy Atlas.Query Delete()
limit Atlas.Query Delete()
offset Atlas.Query Delete()

Lazy loads

Both Row and RowCollection can load automatically other related rows. Just use a property named as related table. For example:

//Get the category id=34
$category = $db->category[34];
//Load the posts of this category
$posts = $category->post;
//This is equivalent to:
$posts = $db->post
    ->select()
    ->relatedWith($category)
    ->get();
//But the result is cached so the database query is executed only the first time
$posts = $category->post;

This allows make things like this:

$titles = $db->post[34]->tag->post->title;
//Get the post id=34
//Get the tags of the post
//Then the posts related with these tags
//And finally, the titles of all these posts

Use magic methods to get a Select query returning related rows:

$category = $db->category[34];
//Magic property: Returns all posts of this category:
$posts = $category->post;
//Magic method: Returns the query instead the result
$posts = $category->post()
    ->where('pubdate > ', date('Y-m-d'))
    ->limit(10)
    ->get();

Solving the n+1 problem

The n+1 problem can be solved in the following way:

//Get some posts
$posts = $db->post
    ->select()
    ->get();
//preload all categories
$posts->category;
//now you can iterate with the posts
foreach ($posts as $post) {
    echo $post->category;
}

You can perform the select by yourself to include modifiers:

//Get some posts
$posts = $db->post
    ->select()
    ->get();
//Select the categories but ordered alphabetically descendent
$categories = $posts->category()
    ->orderBy('name DESC')
    ->get();
//Save the result in the cache and link the categories with each post
$posts->link($categories);
//now you can iterate with the posts
foreach ($posts as $post) {
    echo $post->category;
}

For many-to-many relations, you need to do one more step:

//Get some posts
$posts = $db->post
    ->select()
    ->get();
//Select the post_tag relations
$tagRelations = $posts->post_tag()->get();
//And now the tags of these relations
$tags = $tagRelations->tag()
    ->orderBy('name DESC')
    ->get();
//Link the tags with posts using the relations
$posts->link($tags, $tagRelations);
//now you can iterate with the posts
foreach ($posts as $post) {
    echo $post->tag;
}

Relate and unrelate data

To save related rows in the database, you need to do this:

//Get a comment
$comment = $db->comment[5];
//Get a post
$post = $db->post[34];
//Relate
$post->relate($comment);
//Unrelate
$post->unrelate($comment);
//Unrelate all comments of the post
$post->unrelateAll($db->comment);

Pagination

The select query has a special modifier to paginate the results:

$query = $db->post->select()
    ->page(1)
    ->perPage(50);
$posts = $query->get();
//To get the page info:
$pagination = $query->getPageInfo();
echo $pagination['totalRows']; //125
echo $pagination['totalPages']; //3
echo $pagination['currentPage']; //1
echo $pagination['previousPage']; //NULL
echo $pagination['nextPage']; //2