Pvik is a lighweight PHP framework that uses the model, view, controller principle.
-- EXAMPLE --
Here is a very simple example how you build a website with the framework. I'm asking you if this is easy to understand or just for me because I know the framework and of course if there are things that I can build better. Our sample database looks like this:
Authors
- AuthorID (int, primarykey, auto increment)
- Firstname (text)
- Lastname (text)
Books
- BookID (int, primarykey, auto increment)
- Title (text)
- AuthorID (int)
At first we have to tell Pvik how our database looks like. So we're creating a ModelTable that has field definitions and also Model which will be used as object for a single line (in folder /model/):
<?php
class AuthorsModelTable extends ModelTable {
public function __construct(){
// define the table name
$this->TableName = 'Authors';
// define the class name for the model
// 'Model' is the standard suffix: 'AuthorModel'
$this->ModelName = 'Author';
// define the primarykey
$this->PrimaryKeyName = 'AuthorID';
// define a new attribute from type primary key
$this->FieldDefinition['AuthorID'] = array ('Type' => 'PrimaryKey');
// define a new attribute from type normal (text, number, anything)
$this->FieldDefinition['Firstname'] = array ('Type' => 'Normal');
// define a new attribute from type normal (text, number, anything)
$this->FieldDefinition['Lastname'] = array ('Type' => 'Normal');
// define a new attribute from type many foreign object
// this field contains an ModelArray from 'BookModel's that are associated with a author
$this->FieldDefinition['Books'] = array ('Type' => 'ManyForeignObjects', 'ModelTable' => 'Books','ForeignKey' => 'AuthorID');
}
}
// this phpdoc is usefull for code completion
/**
* @property int $AuthorID
* @property string $Firstname
* @property string $Lastname
* @porperty ModelArray $Books
*/
class AuthorModel extends Model {
public function __construct(){
// define the class name for the model table
// 'ModelTable' is the standard suffix: 'AuthorsModelTable'
$this->ModelTableName = 'Authors';
}
}
?>
and now for books:
<?php
class BooksModelTable extends ModelTable {
public function __construct() {
// define the table name
$this->TableName = 'Books';
// define the class name for the model
// 'Model' is the standard suffix: 'BookModel'
$this->ModelName = 'Book';
// define the primarykey
$this->PrimaryKeyName = 'BookID';
// define a new attribute from type primary key
$this->FieldDefinition['BookID'] = array('Type' => 'PrimaryKey');
// define a new attribute from type normal (text, number, anything)
$this->FieldDefinition['Title'] = array('Type' => 'Normal');
// define a new attribute from type foreign key
// this field contains the real id
$this->FieldDefinition['AuthorID'] = array('Type' => 'ForeignKey', 'ModelTable' => 'Authors');
// define a new attribute from type foreign object
// this field contains a object from type 'AuthorModel'
$this->FieldDefinition['Author'] = array('Type' => 'ForeignObject', 'ForeignKey' => 'AuthorID');
}
}
// this phpdoc is usefull for code completion
/**
* @property int $BookID
* @property string $Title
* @property int $AuthorID
* @property AuthorModel $Author
*/
class BookModel extends Model {
public function __construct() {
// define the class name for the model table
// 'ModelTable' is the standard suffix: 'BooksModelTable'
$this->ModelTableName = 'Books';
}
}
?>
Now Pvik knows everthing about our database (I skip the part where in the config we fill in the login data). The next step is creating a controller (in folder /controllers/), I don't want to overfill this post, so the controller just loads the data and refers to the view.
<?php
class BooksController extends Controller {
// action
public function Overview(){
// load all books
$Books = ModelTable::Get('Books')->LoadAll();
// passing the data to the view
$this->ViewData->Set('Books', $Books);
$this->ExecuteView();
}
}
?>
and of course the view (in /views/books/overview.php #/views/controller name/action name.php ):
<!DOCTYPE html>
<html>
<head>
<title>All books</title>
</head>
<body>
<?php
// getting the data from the controller
$Books = $this->ViewData->Get('Books');
/* @var $Books ModelArray */
?>
<table>
<tr><th>Title</th><th>Author</th><th>How many books did the author write?</th></tr>
<?php
foreach($Books as $Book){
/* @var $Book BookModel */
?>
<tr>
<td><?php echo $Book->Title;?></td>
<!-- Uses lazy loading to get the author -->
<td><?php echo $Book->Author->Firstname . ' ' . $Book->Author->Lastname ?></td>
<td><?php echo count($Book->Author->Books);?></td>
</tr>
<?php
}
?>
</table>
</body>
</html>
The last step is that we have to tell pvik which controller should be called when. Therefor we add a route in the config.php:
self::$Config['Routes'] = array (
array ('Url' => '/books/', 'Controller' => 'Books', 'Action' => 'Overview')
);
If we would access our side now under the URL example.org/books/ Pvik automatically calls the controller, which loads a list of books. Than the view get called which does create the HTML.
Pvik also provides methods to insert/update Models. You could set up a masterpage. Add parameters to a route. As is said this example is just a simple one to show something. If you have further questions don't hesitate to ask me and don't forget to have a look at the documentation which explains it much more in detail.
--- FURTHER EXAMPLE / INFORMATION ---
Some might ask why Pvik uses classes for the definition of a database. This gives you the possibilty to add function to you ModelTable and your Model:
<?php
class AuthorsModelTable extends ModelTable {
// ... //
// returns a AuthorModel or null by its name
public function LoadAuthorByFullname($Firstname, $Lastname){
// this variable indicates if all authors already loaded
// into the cache
if($this->LoadedAll){
// if everything is loaded this functions doesn't run a sql
// instead it loads the authors from the cache
$Authors = $this->LoadAll();
$Author = $Authors->FilterEquals('Firstname', $Firstname)
->FilterEquals('Lastname', $Lastname)
->GetFirst();
return $Author;
}
else {
// we have to run a sql statement
$Query = new Query('Authors');
$Query->SetConditions('WHERE Authors.Firstname = "%s" AND Authors.Lastname = "%s"');
$Query->AddParameter($Firstname);
$Query->AddParameter($Lastname);
$Author = $Query->SelectSingle();
return $Author;
}
}
}
class AuthorModel extends Model {
// ... //
public function GetFullname(){
return $this->Firstname . ' ' . $this->Lastname;
}
}
A new controller:
class AuthorsController extends Controller {
public function Author(){
// get parameters from the url
$Firstname = $this->Parameters->Get('firstname');
$Lastname = $this->Parameters->Get('lastname');
// call our new function
$Author = ModelTable::Get('Authors')->LoadAuthorByFullname($Firstname, $Lastname);
if($Author!=null){
$this->ViewData->Set('Author', $Author);
$this->ExecuteView();
}
else {
// redirects to the root page
$this->RedirectToPath('~/');
}
}
}
?>
Our very simple view:
<!DOCTYPE html>
<html>
<head>
<title>Author</title>
</head>
<body>
<?php
// getting the data from the controller
$Author = $this->ViewData->Get('Author');
/* @var $Author AuthorModel */
// we just display the fullname
echo $Author->GetFullname();
?>
</body>
</html>
And again we need to register the route in the config:
self::$Config['Routes'] = array (
// ... //
array ('Url' => '/author/{firstname}/{lastname}/', 'Controller' => 'Authors', 'Action' => 'Authors')
);
Now we can call our website via example.org/author/william/shakespear/