Is there a PHP framework, that lets me write such code.
class Item
{
private $_id; //primary key
private $name;
private $price;
function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
}
...
$item = new Item(...);
db->Save($item);
...
db->Delete($item);
...
db->Update($item);
...
Item[] = db->Fetch($whereClause);
Yes Admins, I searched on Google, but I got lost in the vast sea (Doctrine, Propel, ActiveRecords,...), asked a different question on SO (which prohibited me from comparison), so I am asking differently now, which framework lets me write such simple code, without much additional coding, no XML, YAML.
Or additionally how to write such if not there. Any pointers will be helpful. Off course I have PHP 5.3 and can use PDO, but performance is a concern (magic functions...), not extensive features list (we support this thing also, that you will never use).
OOPS: forgot to add, don't want a framework like CakePHP, etc. I am writing simple php without frameworks, want just some libraries that I can include into my project and call the above syntax. Its ok for me, if it requires a little SQL behind.
If you do not need a full application framework, for example, you might have written your own framework or if you are not using any framework, I can not recommend Redbean enough. On the plus side, Redbean also has bridges for frameworks such as Zend and CodeIgniter.
I like Redbean because it does not require much configuraion, no YAML, XML or other configuration. The library is very light and quite performant. The amount of features is about "just right", there are no superfluous features, but you do have all the things you need in there. The syntax is also very close to the one you want.
Now the downside: You need to adhere to strict table structures. For example, an ID column is need for link tables. Support for table name prefixes has also been removed in 3.0. However, I don't find these things to be important, so it isn't a huge issue for me.
If it is, you could even fork the library and modify it to your needs.
php-activerecord will probably fit your needs. Model classes should extend from ActiveRecord\Model:
<?php
class City extends ActiveRecord\Model {
// Table name will be defaulted to 'cities', but you can override it
static $table_name = 'mycities';
// Primary key will be defaulted to 'id', you can override it too
static $primary_key = 'city_id';
// Associations
static $belongs_to = array(
array('country')
);
static $has_many = array(
array('citizens', 'class_name' => 'User')
);
}
// Creating
$city = new City(array('name' => 'New York'));
$city->save();
// Find City with id=5, output some data
$anotherCity = City::find(5);
echo $anotherCity->country->location;
foreach ($anotherCity->citizens as $citizen) {
echo $citizen->full_name;
}
This is a very simple example, php-activerecord has some nice features:
Sensible conventions, you can reduce amount of code by following them (in fact, you should follow them if you're starting from scratch)
Validations to enforce business rules
CRUD for manipulating objects in OO-way
Callbacks - advanced pieces of code to associate with different lifetime events of your models
I think a lot of them. ZendFramework is one of such frameworks.
cake PHP is very near to your requirement
search scfolding with cake PHP is very near to your requirement
Thanks
There are many frameworks. See this for an example.
Every frameworks have there own way of API, through which you can use many features, such as db, xml.
For ORM only Doctrine is very Excellent
For rapid development and scaffolding features Codeigniter is very good.
For in-depth framework with many pre-built libraries Zend-Framework is one of the best. It has libraries for Doctrine too.
Related
I'm working in a PHP project where testing software was neglected a long time.
The business logic is full of hard coded dependencies and immediate database access throught some hand-crafted (Oracle) SQL.
I've given up trying to build automated integration tests, because of complex database setup, tight compling to the (complex) database fixture and missing in-memory solutions.
For me it looks like the best place to start, is to test the business logic. Therefore I need to refactor the code to get the data access code seperated from the business logic, I guess. Still I'm struggeling with some basic design questions:
What is the preferred way to encapsulate/get rid of this complex SQL? Is there any design pattern which has some good hints on how to get data from the datasource in an configurable way? Injecting Propel Active Query objects seems the help in some cases, but in complex cases they will be very hard to mock I guess.
Is there a good book about Software Architecture + Unit Testing for Applications that need are heavily making use of their database?
To answer your 2nd question: Working Effectively with Legacy Code is what you need: it explains several pattern to break dependencies to make a code testable.
Regarding your first question: it depends on your current case. Here are a few example described in depth in the book:
Example 1 - Extract and override Call
If you have a classe like (example isn't in php, but you'll get the idea)
class MyClass {
int getNbEligibleItems(){
List<Item> rawItems = readInDb();
//Now count elegible ones
}
List<Item> readInDb(){
//Directly call DB and return a raw list
}
}
Then you could make readInDb virtual, and use a mock in tests:
class TestableMyClass : MyClass {
override List<Item> readInDb(){
//Return a list of hard code test items
}
}
Example 2 - Parametrized constructor
If you have a class like this
class MyClass {
private IDbReader _reader;
MyClass(){
_reader = new DbReader();
}
int work(){
List<item> items = _reader.read();
//Work with items
}
}
Then it would be possible to changes constructors to
MyClass() : this(new DbReader()){ }
MyClass(IDbReader reader){
_reader = reader;
}
So it would be possible to mock db in tests
So, to put it in a nutshell: there are a lot of technique that could help in your case. We' need some code to be more specific. And I recommend reading this book as it provide lot of answers in those cases.
I am building a really minimal MVC framework to increase my PHP knowledge and challenge myself. I've come to the point where Classes begin to be dependent on each other to work.
Dependency injection seems to be the solution to this and are used by some of the big frameworks around.
I've found Bucket on Github and have messed around it for a while to understand the basics. What I can't get my head around however is when it's appropriate to create a Container?
Making one big container including every possible class that may be needed seems nothing but counter-productive to me and I can't imagine that it is good practice. It seems like the recipe for bad performance at least.
In the alternative, which is to make multiple containers, I still don't get how the ever-stinking Singletons are not needed anymore.
Let's say that I would have the following code:
$session_container = new bucket_Container();
$session_container->create('Database');
$session_container->create('Database_Sessions');
$log_container = new bucket_Container();
$log_container->create('Database');
$log_container->create('Database_Log');
So here we have two containers, or in this case buckets for two totally different usages which are mutual by their dependency on the Database class.
My logic tells me that the above code will create two independent instances of the Database-class, meaning that I still would have to make the Database-class a singleton to ensure that concurrent instances of my database connection isn't occurring?
Is this correct?
I don't know much about the specific lib, but assuming it lets you use a factory, let the factory return the same instance.
Edit: Ok, this is simply on the Bucket GitHub index page.
class MyFactory {
function new_PDO($container) {
return new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
}
}
$bucket = new bucket_Container(new MyFactory());
$db = $bucket->get('pdo');
So in your case you could simply do:
class MyFactory {
private $pdo;
function new_Database($container) {
if($this->pdo){
return $this->pdo;
}
return $this->pdo = new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
}
}
$factory = new MyFactory();
$session_container = new bucket_Container($factory);
$session_container->create('Database_Sessions');
$log_container = new bucket_Container($factory);
$log_container->create('Database_Log');
Something like that. Doesn't seem like rocket science.
Edit2: I don't have enough rep points to comment on the question (bit silly), but in response to your "modularity" concern: think of the container as the "glue" of your application. Indeed, if you have a large application, you may want to "glue" inside an isolated part of your application only. That is a valid encapsulation concern. But even then you still need a container that handles injection at the highest level of abstraction. If you just create a separate container for every part of your application, you either end up with unneeded duplication of instances, or you have to apply another level of instance management, which doesn't improve the encapsulation in any way: you're still sharing instances between different parts of your application.
My advice would be to use a single container at the bootstrap level. If you want added encapsulation for specific parts of your application (modules, plugins, whatever), use "child containers". A child container inherits the instances from the parent container, but the parent container knows nothing of the child (as far as he's concerned, he's still a bachelor ;)). Could be that Bucket supports this by default, I know other DI containers do. If not, it's really easy to implement using a Decorator. Imagine something like this:
class MyContainerType extends bucket_Container {
private $_parent;
private $_subject;
public function __construct($factory = null, bucket_Container $parent = null){
$this->_parent = $parent;
$this->_subject = new bucket_Container($factory);
}
public function get($key){
$value = $this->_subject->get($key);
if($value){
return $value;
}
return $this->_parent->get($key);
}
/**
* Override and delegation of all other methods
*/
}
Making one big container including every possible class that may be needed seems nothing but counter-productive to me and I can't imagine that it is good practice. It seems like the recipe for bad performance at least.
On the contrary. This is exactly what you would do with a di container. The container will only instantiate objects on demand, so there is virtually no overhead to managing all you singleton-ish classes through it.
The biggest problem with di is to distinguish between shared objects (Things you would usually think of as singletons) and transient objects (Objects that have plenty of instances through a normal application flow.). The former are easily managed through di. The latter don't really fit. Having those two "kinds" of objects clearly distinguished may seem like a bit of a hassle, but is really a highly beneficial side effect of using a di container.
If you are worried about multiple simultaneous connections you can just use mysql_pconnect() or the equivelant for the database you are using. It will check if a connection is already open and use the existing connection if it is.
As far as the container issue, I've seen it done in two ways, which you seem to be aware of both. The first method is to have the framework read your database schema and create classes fore each table. I personally don't like this approach. Symfony is one framework that does this (by using the doctrine ORM).
The more preferred method I've seen is to have a generic container, which basically builds the sql for you given a table, columns and an action. This is the approach taken by codeIgniter:
$query = $this->db->get('mytable');
$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);
I'm starting with CodeIgniter and after several hours diving in Google I'm a bit confused.
Let's try to explain my question with a easy example: I have a table 'car' with the fields 'name' and 'color'. Therefore I want to have a php class Car, so that my code could look finally like this:
$car = new Car('BMW', 'red'); //new $car Object
$car->save(); //this will make an SQL insert to the table 'car'
//Lets query all cars
$cars = Car::get_all();
//cars will be an array of Car objects, (not a set of rows!)
Therefore, I am looking for something pretty similar to what you have in RubyOnRails or Django (Python). I need to handle all kind of relationships, and to be able of write code in a true OOP+MVC way.
These are my failed approaches to get it:
Using an external ORM (DataMapper, Doctrine, AcidCrud...)
They either requires too many settings, or they handle relationships in a poor way.
Using CodeIgniter classes (to extend the CodeIgniter's Model class)
class Car extends Model{
public function Car($name='',$color='')
{
$this->name = $name;
$this->color = $color;
parent::Model();
}
public function save()
{
$data = array(
'name' => $this->name ,
'color' => $this->color
);
$this->db->insert('cars' $data);
}
And so on... Problem with this approach is that if a do a var_dump() of a $car object, I see that it contains a lot of stuff from the CodeIgniter, such as the objects CI_Config, CI_Input, CI_Benchmark, etc. Therefore I think this is not a good solution, because each object of my class Car, it will contain a lot of repeated data, (it will have a poor performance!), isn't it?
Not using the CodeIgniter's models
I could make my models without extending them from CodeIgniter's Model class, and then using the regular PHP5 constructor (__construct() instead of function Car()), but problem in this case is: how I access to the $db object to make querys using the CodeIgniter's ActiveRecord? and, how I load the models (its classes) within the controllers?
You probably want something like this:
class Cars {
//List all neccessary vars here
function __construct() {
//get instance of Codeigniter Object and load database library
$this->obj =& get_instance();
$this->obj->load->database();
}
//You can now list methods like so:
function selectCar($name, $color) {
$this->obj->db->select('color')->from('car')->where('color', $color);
$query = $this->obj->db->get();
switch ($query->num_rows()) {
case 0:
return false;
break;
default:
return $query->result();
break;
}
}
Hope that helps!
Try with Doctrine, is a great ORM and can be easily integrated in CodeIgniter.
take a look the the codeigniter wiki page for ORM
http://codeigniter.com/wiki/ORM/
For future Googlers, here is a tutorial I wrote up about how to integrate CodeIgniter 2 with Doctrine 2.
Let me know if you have any issues.
I had good luck with using Propel with codeigniter.
check out GAS ORM it sounds pretty good, handy and easy to use.
some features of this ORM implementation for CodeIgniter:
Supported databases : cubrid, mssql, mysql, oci8, odbc, postgre, sqlite, sqlsrv. (including PDO, if you keep sync with CI repo)
Support multiple database connections.
Support multiple relationships.
Support composite keys (for key that define relationships).
Auto-create models from database tables and vice versa.
Auto-synchronize models-tables by creating migrations file.
Per-request caching.
Self-referential and adjacency column/data (hierarchical data).
Eager Loading to maximize your relationship queries (for performance manner).
Various finder methods (can chained with most of CI AR) and aggregates.
Validation and auto-mapping input collection with minimal setup.
Hooks points to control over your model.
Extensions to share your common function/library across your model.
Transactions and other CI AR goodness.
Included phpunit test suite to ensure most of API consistency.
there is one form with spark support -> so it's easy to install
What you want to do is create a library that extends the ActiveRecord class. Some people are ahead of you:
http://codeigniter.com/wiki/ActiveRecord_Class/
good mods in the thread, here:
http://codeigniter.com/forums/viewthread/101987/
If you're looking for ORM methods that are general to your app, just extend the ActiveRecord class. For my application, knowing the structure of a table allows me to scaffold (auto-generate) forms, and do other mapping. I do API-to-API mapping, so I include a GetStructure() method in MyActiveRecord and build other things from there.
(RoR snickering can bugger off now)
Edit: while I am a fan of the scope and power of Doctrine, I think it's demand for command-line usage places it beyond the spirit of CI. What's right for you is what's right for you, but if I'm going to use Doctrine, I might as well use Symfony, right? Or RoR, for that matter, right?? See where I'm gong with this? Right tool for the right time.
I used CodeIgniter with Propel and they really mixed well. I've used like that for a while and got a few webapps working that way. Since I found a few awful ways to do it ( some included modifiying Apache's configuration!!). I decided to publish a blog post on how to do it. You can read it here.
Hope I can help!
I think php-activerecord is a very good drop-in ORM. I've used it with the Slim Framework a few times and I think it would be a great alternative to using CI's native model class. Here is some sample code and the link:
$post = new Post();
$post->title = 'My first blog post!!';
$post->author_id = 5;
$post->save();
PHP ActiveRecord
i know this is quite old, but for those who are just using codeigniter now and wannt to use an orm with it can use this tutorial to integrate propel with codeigniter
http://llanalewis.blogspot.com/2013/06/installing-propel-in-codeigniter.html
I am trying to learn OOP. The so called 'real world' examples in the books I am reading aren't helping.
All the examples like Pet, Car, Human aren't helping me anymore. I need REAL LIFE examples that like registration, user profile pages, etc.
An example:
$user->userName = $_POST['userName'];//save username
$user->password = $_POST['password'];//save password
$user->saveUser();//insert in database
I've also seen:
$user->user = (array) $_POST;
where :
private $user = array();
Holds all the information in an array.
And within that same class lies
$user->getUser($uid);
// which sets the $this->user array equal to mysqli_fetch_assoc() using
//the user id.
Are there any real world examples implementing OOP in the many different php applications (registration, login, user account, etc)?
OOP is not only about how a single class looks and operates. It's also about how instances of one or more classes work together.
That's why you see so many examples based on "Cars" and "People" because they actually do a really good job of illustrating this principle.
In my opinion, the most important lessons in OOP are encapsulation and polymorphism.
Encapsulation: Coupling data and the logic which acts on that data together in a concise, logical manner
Polymorphism: The ability for one object to look-like and/or behave-like another.
A good real-world example of this would be something like a directory iterator. Where is this directory? Maybe it's a local folder, maybe it's remote like an FTP server. Who knows!
Here's a basic class tree that demonstrates encapsulation:
<?php
interface DirectoryIteratorInterface
{
/**
* #return \Traversable|array
*/
public function listDirs();
}
abstract class AbstractDirectoryIterator implements DirectoryIteratorInterface
{
protected $root;
public function __construct($root)
{
$this->root = $root;
}
}
class LocalDirectoryIterator extends AbstractDirectoryIterator
{
public function listDirs()
{
// logic to get the current directory nodes and return them
}
}
class FtpDirectoryIterator extends AbstractDirectoryIterator
{
public function listDirs()
{
// logic to get the current directory nodes and return them
}
}
Each class/object is responsible for its own method of retrieving a directory listing. The data (variables) are coupled to the logic (class functions i.e, methods) that use the data.
But the story is not over - remember how I said OOP is about how instances of classes work together, and not any single class or object?
Ok, so let's do something with this data - print it to the screen? Sure. But how? HTML? Plain-text? RSS? Let's address that.
<?php
interface DirectoryRendererInterface
{
public function render();
}
abstract class AbstractDirectoryRenderer implements DirectoryRendererInterface
{
protected $iterator;
public function __construct(DirectoryIteratorInterface $iterator)
{
$this->iterator = $iterator;
}
public function render()
{
$dirs = $this->iterator->listDirs();
foreach ($dirs as $dir) {
$this->renderDirectory($dir);
}
}
abstract protected function renderDirectory($directory);
}
class PlainTextDirectoryRenderer extends AbstractDirectoryRenderer
{
protected function renderDirectory($directory)
{
echo $directory, "\n";
}
}
class HtmlDirectoryRenderer extends AbstractDirectoryRenderer
{
protected function renderDirectory($directory)
{
echo $directory, "<br>";
}
}
Ok, now we have a couple class trees for traversing and rendering directory lists. How do we use them?
// Print a remote directory as HTML
$data = new HtmlDirectoryRenderer(
new FtpDirectoryIterator('ftp://example.com/path')
);
$data->render();
// Print a local directory a plain text
$data = new PlainTextDirectoryRenderer(
new LocalDirectoryIterator('/home/pbailey')
);
$data->render();
Now, I know what you're thinking, "But Peter, I don't need these big class trees to do this!" but if you think that then you're missing the point, much like I suspect you have been with the "Car" and "People" examples. Don't focus on the minutiae of the example - instead try to understand what's happening here.
We've created two class trees where one (*DirectoryRenderer) uses the other (*DirectoryIterator) in an expected way - this is often referred to as a contract. An instance of *DirectoryRenderer doesn't care which type of instance of *DirectoryIterator it receives, nor do instances of *DirectoryIterator care about how they're being rendered.
Why? Because we've designed them that way. They just plug into each other and work. This is OOP in action.
Purchase a book like "PHP and Mysql everyday apps for Dummies".
Its old I know [2005] but it shows concepts of User Logins, Forum, Shopping Carts, etc in both Procedural and Object Oriented with Mysqli.
It helped me learn Object Oriented PHP, I studied it a lot. Well worth the money.
OOP is much like grouping bits of your program into reuseable pieces. Its not that hard to be honest with you its just the idea of packing your functions into classes.
Real world mini example of OOP stuff below:
CLASS DATABASE
CLASS SESSIONS
CLASS WEBFORMS
CLASS EMAIL
CLASS ACCOUNTS (Example Functions below)
FUNCTION SELECTACCOUNT
FUNCTION CHECKPASSWORD
FUNCTION CHECKUSERNAME
FUNCTION CREATEACCOUNT
I hope you keep at it, PHP 6 will be re-engineered to support OOP more than ever.
Good Luck!
Whilst I know that this question has been answered already, I feel as though I can add value here.
I don't believe that you should use PHP as a programming language to learn OOP. If you wish to learn OOP for web applications, you should really be looking at C# or Java. Once you have learned OOP, then you can apply this knowledge to PHP. One example of a book I used to learn OOP was Big Java by Cay S. Horstmann
Why do I say this??? Because there are literally millions of examples on PHP of how to do stuff, however not many are examples of how to program properly. Further to this, PHP allows you to take many shortcuts, which would not be acceptable with the likes of Java. As such, if you program PHP with a Java head, then I believe that you will be a stronger programmer. OOP is not language specific, it is a programming paradigm.
If you must learn OOP using PHP, then I would recommend that you take a look at some real source code in public repositories of github. You can search them in packagist.org. If they are a decent public repository, they will contain a readme.md file which would show you how to use the composer packages. e.g https://github.com/moltin/laravel-cart is an example of a shopping cart package which you would be able to use in your application. Notice how you don't need to look at the package source code to understand what the packages do. The package has been written, and you don't care about how they work, but you use them so you only need to know how to use them. This is exactly what OOP is about.
I don't care how the shopping cart class adds an item to the cart, I just want to create a new cart and add something to it.
What you are doing however is diving into the source code as a tool to understand how OOP works.
Further to this, and probably more importantly, for web application development, I would research the MVC design pattern.
The MVC design Pattern stands for Model, View, Controller. Where in the case of a web application, The Model is responsible for modelling the database, the view is responsible for displaying content to the user. The controller is responsible for interacting with the model and handling user input.
I then think you should try to install the Laravel Framework or other "decent modern framework" on your local machine. Why do I say modern, because modern frameworks require a minumum PHP version of 5.3+ which mean that the PHP on your machine would support real OOP similar to that which you would get from the likes of Java.
There are many tutorials which will show you how to build web applications in laravel. Immediately, you will see that when you create a controller, you extend a BaseController. When you create a Model, you extend Eloquent. This means that you will already be using Polymorphism in your code. You will see that by using classes, they are being encapsulated, and you will see that each class has a specific role.
When you would like to interact with the database, you will initially create a new Model object within the controller methods. As you start to learn more, you will start learning how to inject dependencies into the controller, then learning how to dump your models and create repositories and program to interfaces instead.
A decent book on learning Laravel for beginners would be https://leanpub.com/codebright by Dale Rees. I met Dale at a Laravel meetup about 2 weeks ago.
Further to this, as you become more proficient building web applications, you will start to learn how to apply the following principles to your programming:
Single Responsibility Principle
Open Closed Principle
Liskov Substitution Principle
Interface Segragation Principle
Dependency Inversion Principle
As astropanic said, you could take a look at the source code of a good PHP framework or library. I recommend Zend Framework, it's very modular and has a great, professional design. I would say it is a very good piece of object-oriented PHP code.
Still, I think it's not that easy to learn from a huge piece of production code, since it wasn't really made to teach you anything. But if you want real-world object-oriented PHP code, the Zend Framework (or Symfony, or maybe CakePHP) is probably the way to go.
I'd advise you to stay away from any framework at this moment, if you do not know OOP, digging into zend or any other framework would be too much.
PHP OOP is quit funny... like ha ha funny, because it's supported, but PHP is not an OOP language like java or c#.
Short example just to underline my statement:
// define class
class User {
// define properties and methods
public $name = "";
}
// instantiate class
$user = new User; // or new User() or new user, it's all the same
echo $user->name;
but if you want to do OOP "on the fly" you can do the following:
$user = (object) array('name' => 'Peter');
and then
$user->name;
but you can use OOP like you would in java or c# but not to the same extend - and have in mind, popular systems like wordpress and drupal are not pure OOP! but you can do inheritance and other classing OOP stuff in PHP as well.
I haven't gone far in PHP OOP, but the more i get into it the more easier it becomes. The objects examples are just there for you to understand how OOP works. I understand and been through this before, OOP is just about properties and methods ( normal variables and functions). I programed in real OOP myself applying the examples from my tutorials and didn't necessarily have to be in real world. That is just like been spoon fed and you would never understand OOP and would be easy to forget. My advice learn to understand. If you understand, you can do anything and would realize the power of OOP. I downloaded this book and i think you should too. But that is just like someone building your apps for you...
Here a link to the book PHP and Mysql everyday Apps For Dummies
you're right 99% of the tutorials that you'll find online are too basic, and they don't make sense. My suggestion to anybody trying to learn object oriented programming is:
find some code that you've written in procedural programming and try to convert it into OOP.
Take all your variables and make them a properties of a class, find a suitable class name. Then take all your functions, if you have functions, and group them within a class. If you wrote your code without using functions, first try to convert your code into a group of functions. find suitable function names, a function should define what a piece of code does. Once you have your functions move them into a class.
I'll give you a simple example of a pagination code that I converted into a reusable pagination class. find the full tutorial on youtube: https://www.youtube.com/watch?v=X38IRlyY_ww&t=91s , link to the source code is on the description box
class Paginator{
/*the class need to know the current page to calculate the offset
the offset tell my sql how many rows to skip */
private $current_page;
//the limit is the number of results to display per page
private $limit;
/*pagination links to display below the results with next
and previous button*/
private $pagination_links;
//the last page of your pagination links
private $last_page;
.
. etc
public function __contruct($number_of_rows_found,$results_to_display_per_page){
//the paginator uses the number_of_rows_found to determine the last page
$this->last_page = $number_of_rows_found/$results_to_display_per_page;
//get the current page, set it to 1 by default
$this->current_page = isset($_GET['page']) ? ($_GET['page'] : 1;
}
public function generate_pagination_links(){
this method uses the last_page property to generate pagination links
if the last page is 3, this will give you 3 pagination links
for ($page = 1; $page <= $this->last_page; $page++) {
//use
}
}
public function get_offset_and_limit(){
//this method calculates the offset based on the current page
return "LIMIT $this->per_page OFFSET ".($this->page - 1) * $this->per_page;
}
.
.
.etc
}
}
Then to use the pagination class, you create a new instance of it, and pass the
number of results you want to display per page, and the the number of results returned
by your query as parameters. The pagination class will generate pagination links for
you and calculate the offset and limit. That's a good example of a php reusable
class, you can use it in your multiple projects without having to rewrite or change it.
$paginator = New Paginator($rows_found,8);
$pagination_links = $paginator->get_pagination_links();
$offset_and_limit = $paginator->get_offset_and_limit();
//apend the limit and offset to your sql query
$query = $query. ' '.$offset_and_limit;
$connection = getdbconnection();
$stmt = $connection->prepare($query);
$stmt->execute();
$movies = $stmt->fetchAll();
Ofcourse there're more advanced concepts into OOP that are not covered in this example, but this should give you a basic understanding of how classes and objects work
I suggest also to see my wrapper Arrayzy. It's a native PHP arrays easy manipulation library in OOP way.
So if you work with native PHP array functions - you could do the same things in OOP and Arrayzy helps you with it, for example:
// Functional programming:
$array = ['a', 'b', 'c'];
$resultArray = array_merge($array, ['c', 'd']);
and
// Object-oriented programming:
$obj = Arrayzy\MutableArray::create(['a', 'b', 'c']);
$obj->mergeWith(['c', 'd']);
$resultArray = $obj->toArray();
In both cases the result array will be:
Array(
0 => 'a'
1 => 'b'
2 => 'c'
3 => 'c'
4 => 'd'
)
Check how does this mergeWith method (or other) works under the hood.
I think this is a nice example which shows that almost everything functional code you could replace with OOP code like in this library. But with OOP you get much more and you could also check Functional programming vs OOP question to learn more details what's a cons and props of it.
From a maintenance and code organization standpoint, in PHP5, does it make sense to create/define objects and classes for XML data coming from a web service?
Using Twitter's API as an example, I would have a class for each API method (statuses, users, direct_messages, etc). For statuses/public_timeline, I would have something like this:
class Statuses {
public $status = array(); // an array of Status objects
public function __construct($url) { // load the xml into the object }
}
class Status {
public $created_at, $id, $text; // and the rest of the attributes follow...
}
$public_timeline = new Statuses('http://twitter.com/statuses/public_timeline.xml');
echo $public_timeline->status[0]->text;
Or is it better to dump everything into an associative array, so items would be accessed like this:
// the load_xml function is just something that will dump xml into an array
$public_timeline = load_xml('http://twitter.com/statuses/public_timeline.xml');
echo $public_timeline['statuses']['status'][0]['text'];
First design:
Strictly following object-oriented principles
Seems like an approach better suited for compiled languages
Second design:
A lot less maintenance would be needed if the API is modified. If the API adds an attribute to the XML, the corresponding class would need to be updated in the first design.
I think this depends on your project ...
First design:
Strictly following object-oriented principles
Seems like an approach better suited for compiled languages
Necessary in a big application
Easy to reuse
Benefiting when passing data around
You have methods to add functionality, not just data
Second design:
A lot less maintenance would be needed if the API is modified. If the API adds an attribute to the XML, the corresponding class would need to be updated in the first design.
Straight forward & quick solution
Little code
I'm with Philippe: if your application is going to be really small (just calling the status methods for example), go with solution 2.
I agree that creating a bunch of classes just to echo status informations isn't really needed in the first place. But if your application it's going to be huge, design with solution 1 in mind. As you go along with your development, you're going to create specific methods that would belong to specific classes. Sometimes you would like to create a method to "order" status messages. Who knows? That's why we create classes, each one with it's own responsibility, so you wouldn't need to search a big php file with hundreds of functions.
I do believe that if you don't know how your application is going to grow, a "best-of-both worlds" approach would be creating classes to at least each Twitter categories (Timeline, Status, User, etc, totalizing maybe 12), instead of each method. Is a good solution IMO in your case, if you don't want to create too many classes.
If you're working with XML in PHP5 then I think the best would be to use SimpleXML. Then you have the best of both worlds. You can access your values in a very array-like way. However you can extend SimpleXML class to provide methods and other custom nice-to-haves.
// To get the effect of an array...
$twitte = 'http://twitter.com/statuses/public_timeline.xml';
$public_timeline = simplexml_load_file($twitte);
echo $public_timeline->statuses->status;
Or extend the SimpleXml Class
class MyXml extends SimpleXml
{
public function quickStatus()
{
$status = $this->xpath("/statuses/status");
return (string)$status[0];
}
}
// then access like
$twitte = 'http://twitter.com/statuses/public_timeline.xml';
$public_timeline = simplexml_load_file($twitte, 'MyXml');
echo $public_timeline->quickStatus();
The above example is just to show how to extend the class. If you'd like more info you can check out the XML class from a library I've created on Google Code