The title may be a little vague, but the question is difficult to word properly.
I'm trying to learn PHP OOP (coming from Procedural) and it's a pain - my main stump is selecting from a databased based on a certain value that is usually passed through the URL (at least in procedural).
For example, user.php?ID=2 - then I could quickly define ID using GET and future queries would use that ID.
Since my OOP classes would be in a seperate file to the main page that includes the html and outputs everything, users won't be submitting the ID to that file. In other words, they'll be going to user.php?ID=2 instead of user_c.php?ID=3 which is the class file.
My question is - how do I pass that ID through to the class? I need to select things out of the database based on the profile that they're viewing, but how do I tell the class that?
My apologies for how badly this is worded.
One would do something like this, $data now contains the data returned from the query:
//user_c.php:
Class MyUserClass {
public function getUser($id){
//Query for user data.
return $queryData;
}
}
//user.php
$userClass = new MyUserClass ();
$data = $userClass->getUser($_GET['ID']);
First of all, OOP is not that much different than procedural. The main difference is that instead of data and functions which operate on the data you have objects which encapsulate the data as well as the operations which are valid on that data.
However, in its core, OOP does encapsulate procedural programming, with the difference being that the procedural part happens within objects rather than in the application level.
To migrate from procedural to OOP all you need to do is separate your code in parts which are logically connected, in the case of databases what typically happens is each database table has a class (in MVC frameworks this is called a data model).
For example if you have a table called users you might have a corresponding User class.
class User {
private $id;
private $alsoOtherProperties;
public function __construct($dbconnection, $id) {
//Load the user from id
}
/* Setters and getters and other function here which operate on the user */
}
You then create an instance of a user which you construct from the $id given the database connection. The simplest way is do what you're already doing to get the id. From here on your data will be operating on the User object rather than on a database result. This way you don't have to worry about changing the database structure since you can just update the model to work with the new structure and the rest of the code will not need altering.
For example, say you want to update the "last logged in" column for a user at the time of log in:
//Other code around here
$ID = $db->real_escape_string(strip_tags(stripslashes($_GET['ID'])));
$user = new User($db,ID);
$user->setLastLogin(time());
$user->save();
In this example there's 2 functions defined in the class User in addition to the constructor which is to set the last login time and then update the database row which corresponds to the user. As you can see, this does not have any MySQL specific logic and the underlying code in the user class can update either a MySQL database, a text file, or not do anything (e.g. when just running tests).
Note: This is just an example, probably not a very good one at that, you should really really study OOP to learn more about it.
First and foremost you will need to create a simple database class that will handle your queries.
class DatabaseQuery {
public $parameters;
public $statement;
function __construct($statement,$parameters)
{
global $connection; //this will be your new PDO connection details
$sth = $mysqli->prepare($statement);
$sth ->execute($parameters);
$this -> executedStatement = $sth;
}
function getDetails()
{
$r_result = $this -> executedStatement;
$r_result2 = $r_result->fetch();
$show_result = $r_result2['0'];
return $show_result;
}
function executeStatementOnly()
{
return "Action Successful";
}
function __destruct()
{
//echo "Has been destroyed";
}
}
Next you will pick data from user, you will need to sanitize it using this function
function clean_data($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
Next, pick the data and call your database query class and save or echo the data you are picking.
$get_data = clean_data($_GET["id"]);
$user_details = new DatabaseQuery("SELECT column FROM table WHERE id=?",array($get_data));
echo $user_details->getDetails();
Assuming that until now you did something like this:
// user.php
$id = $_GET['id'];
$myResult = myDbFunction($id);
function myDbFunction($id) {
// do something useful
}
you can re-write this like that:
// user_c.php:
Class MyClass {
public function myDbFunction($id) {
$something = "";
// do something useful
return $something;
}
}
// user.php:
include "user_c.php";
$myClass = new MyClass();
$id = $_GET['id'];
$myResult = $myClass->myDbFunction($id);
And that would produce the same results as if you had placed your class in the same file, like this:
// user.php:
Class MyClass {
public function myDbFunction($id) {
$something = "";
// do something useful
return $something;
}
}
$myClass = new MyClass();
$id = $_GET['id'];
$myResult = $myClass->myDbFunction($id);
I assume you know that one of the main reasons for going OOP over procedural is the re-usability as well as information hiding (i.e. sparing a user of your class the need to understand every detail of it, while still allowing them to use it)
You may want to read up on OOP with PHP, and simply play around with it. While there is a slight differece in the two styles, you should get a hang of it quickly.
Once you make sure you understood the single responsibility principle and follow it, you will surely find that OOP has many advantages over procedural programming.
Related
I have three classes:
Database
User
Page
Each does as it implies.
So, both User and Page need to connect to the database to get their data (User info, page content) - They both get access to the database via dependency injection from Database, and that's perfectly fine. However, Page also needs to display data gotten by User.
This becomes problematic because if I were inject User into Page, wouldn't that technically prompt Page to have TWO instances of the database, both it's own and the one exists in User? That's not good practice, correct?
From I can gather, 'extending' is not the proper solution in this case either. Page is not directly related to User, so they needn't become one.
So, I have two questions:
Would it be 'proper' to channel the database object injected into User to Page by injecting User into Page?
And, if not, what's the proper way to do this?
I think you have some misapprehension about how references work. Let us say I create a database object:
class Database {
function talkToDb(){
//does some database stuff
}
}
Now, lets say I want to have a User class that accesses a Database object - presumably for reading and writing to a persistence layer:
class User {
persistence = null; //This 'points' to a database object that is injected on object instantiation.
function __construct(Database $db) {
$this->persistence = db;
}
}
To create a User you would do the following, somewhere in code:
$db = new Database();
$aUser = new User($db);
$bUser = new User($db);
At this juncture $aUser and $bUser are using the same Database object. Lets talk about Page: it's instantiation is eerily similar to User:
class Page {
$persistence = null;
$someUser = null;
function __construct(Database $db, User $user) {
$this->persistence = $db;
$this->someUser = $user;
}
}
You'd then create - again, somewhere else in code - the Page class. Like so:
$db = new Database();
$aUser = new User($db);
$aPage = new Page($db, $aUser);
At this juncture, the object fields in both $aUser and $aPage are pointing to the same Database object: the one named $db (at least, it is named that in the scope in which we create it above). $aPage also holds a reference to $aUser. Because it has two references - one to the user and one to the database - it could in theory access that same database objects two ways:
class Page {
... //construct everything as above
function accessExample() {
//The following two lines call the exact same function on the exact same object
$this->persistance->talkToDb();
$this->someUser->persistance->talkToDb();
}
}
Remember: when you 'inject' an object into two other objects, you're not copying that object, you're simply copying the reference to the object. It is appropriate for many objects to hold copies of the same reference.
The fact that you can get to the database either way doesn't mean you should. You can mask the User's database from Page by making it private. That said, not doing so is only a matter of code cleanliness: you still can.
Note that it is entirely inappropriate to 'extend' either Page or User from one another or from the Database. An extended class is really a 'subset' or a 'more specific form' of the previous. A User is not a special form of a Database: a MySqlDatabase is. Rather, we know that a User needs to have a database it can 'persist' it's state to. This is why we provide it with a 'reference' to some Database object. We should provide the same reference to all such objects that require access to that same Database. The fact that many objects may hold a reference to the same database object is immaterial: why would this cause a problem?
(Caveat emptor: I'm not actually running the above code, so there may be minor bugs.)
Use a constructor in the database class and set it to a class property.
Assume its available in both user and page classes as you extend our from it.
<?php
class Database
{
}
class MySql extends Database
{
private $sDbName = '';
private $sUsername = '';
private $sPassword = '';
private $sHost = '';
private $oConnection = null;
public function __construct()
{
$this->oConnection = new PDO(
'mysql:host='
. $this->sHost
. ';dbname='
. $this->sDbName,
$this->sUsername,
$this->sPassword
);
}
public function getDb()
{
return $this->oConnection;
}
}
class User extends MySql
{
}
class Page extends User
{
}
$oPage = new Page;
var_dump( $oPage->getDb() );
?>
Sorry if I am not using the best jargon, but I have run into an issue I want to solve early before I write too much code. Which of these options below is "better"? And is there a better way of doing this? Someone mentioned to me abstracting my code but another class seems to be the last thing I need. Also I feel like there's something I can do by potentially making my "get" function seen below into a public static function so that I can use it differently. (its not static right now)
Here is my situation:
I have 2 (relevant to this question) classes, DB (database) and Page (for getting my content to display on my website)
the DB class has a query method that prepares and execute my queries
the DB class also has methods for inserting, getting, deleting things from the database.
I now feel that I may not even need my page class because right on the webpage I can just use those DB methods to call my content. (I store all images, content, page title, description in mysql). Is this not a legitimate way to do this? Won't I need to create a new object each time? such as:
$pg_ID = 2;
$title = new DB($pgID);
$title->get('pages', $pgID, $lang); // 3 tables to pull from for each page
$images = new DB($pgID);
$images->get('images', $pgID, $lang);
$structure = new DB($pgID); // I need these tables mostly because my site is in two languages
$images->get('pages_list', $pgID);
I do not like this potential solution just because to me its counter intuitive. Why should I have to create new objects just to reuse a function? However, what I do right now is something I feel is going to get me some hate mail.
$page = new Page();
$page->find('pages', $pgID, $lang);
$page->lookup($pgID);
$page->retrieve('images', $pgID, $lang);
These are 3 separate functions in my Page class that perform very similar things. Find gets my pages content out of the database and returns it as an object. Lookup does basically the same thing but only needs to pass one variable because its only to do with the html structure of each page regardless of which language is being accessed. retrieve gets all images from a table that get shown in a slider with different language descriptions. But as you can see, all three functions do basically the same thing! They query the database. Thanks for the help with this I am literally just getting into this OOP and its driving me insane. Stack has been very helpful and I think I just didn't know how to search for this to find the answer. Feel free to point me to other questions/answers that I may have missed. It was hard for me to think of the keywords to search for.
we may create other classes indeed, but efficiently so. Maybe we can render DB a public state function. I like the idea of creating a database object, pass it as parameter to an other object, which could then format data with the link he just received:
$pg_ID = 2;
$db = new DB($pg_id);
$page = new Page($db,$pg_ID);
// make sure you assign the parameters a private properties in `Page()` ctor.
then, from inside your function, you can call images, titles and structures at will from $this
$title = $this->DB->get('pages', $this->pgID, $lang);
$images = $this->DB->get('images', $this->pgID, $lang);
$structure = $this->DB->get('pages_list', $this->pgID);
and you can those other method as well
$page->find('pages', $this->pgID, $lang);
$page->lookup($this->pgID);
$page->retrieve('images', $this->pgID, $lang);
Now we do not need to create a new object each time we want information from the database.
Now...
the way I access member functions here $this->pgID is better used by defining a getter: $this->pgID(). I like my getter to have the same name as the property. This might not be a very good idea though.
private function pgID() {
return $this->pgID;
}
As for abstract classes..
I did in fact come very lately into thinking abstract classes were quite cool indeed. I've some problem with wording it, having a constant constructor with custom mandatory functions and possible different implementation of classes seems awesome:
abstract class Page {
function __construct($db,$pgID,$lang,$params='') {
$this->db = $db;
$this->pgID = $pgID;
$this->lang = $lang;
$this->init($params);
}
function pgID() {
return $this->pgID;
}
function lang() {
return $this->lang;
}
abstract function init();
abstract function retrieve();
}
class Structure extends Page {
function init($params) {
// some specific to Structure foo here
}
function retrieve($what='pages_list') {
return $this->db->get($what,$this->pgID,$this->lang);
}
}
class Image extends Page {
function init($params) {
// some specific to Image foo here
}
function retrieve($what='images') {
$images = $this->db->get($what,$this->pgID,$this->lang);
// plus some foo to resize each images
return $images;
}
}
ok, hope you're still there! Now we have a Structure and Image class with requisites constructor arguments, generic functions and a custom retrieve function. We could use them that way:
$db = new DB(2);
$template = new Structure($db,2,'fr');
$template->retrieve();
$slideshow = new Image($db,4,'en');
$slideshow->retrieve();
I do hope you do not have to create a new instance of DB if you use a different page id :-)
jokes appart this helps me using classes in a better structured way, as I might have many different classes to represent different parts of a site, but when called from an index all of them will have the same function names, like retrieve() or print(), list()...
I don't want to get into the weeds on a SPECIFIC implementation for you situation, rather I am going to offer some generic guidance.
First off, you shouldn't have to create a separate database object (dbo) for title, images, or structure. Chances are the DSN used for each dbo you are initializing are the exact same, so I would create a singleton dbo which can be shared across multiple objects. For reference take a look at Doctrine's connection manager.
Secondly, I think your objectification could be implemented better. Following most ORMS implementation, you have a Record class and a Table class. The Record class is a specific instance of a Record in your schema, whereas the Table class executes queries against your store which may result in multiple records. These results are then hydrated into an array (of records).
So what I would suggest is something like this (code has not been tested and some of it has been stubbed for brevity):
class PageTable
{
public static function getById($id)
{
// Validate id, if invalid throw exception
$dbo = Database::getConnection();
$stmt = $dbo->prepare('SELECT * FROM page WHERE id = :id');
$stmt->bindParam(array('id' => $id));
$stmt->execute();
$result = $stmt->fetch();
$page = new Page;
// Hydration
$page->setId($result['id']);
$page->setImages($result['images']);
return $page;
}
}
class Page
{
protected $id;
protected $title;
public function setId($id){}
public function getId(){}
}
Hopefully this separation of Record and methods affecting a single, or multiple records makes sense. You should take a look at a DBAL, like Doctrine.
I have recently been working on a project that was thrown upon me at work after another developer left (he was the only one working on it prior to leaving). The project was written in CodeIgniter and uses the MVC framework. While working on the project I noticed something funny or at least something I have not seen before.
After the model is loaded into the controller the object is passed into the view using...
$data['outcomes'] = $this->id_conversion;
With id_conversion being the model that was loaded in at the top of the controller. My question is is this any different then using
new Id_conversion();
in place of the above.
Thanks for any help or anyone able to point me in the correct direction.
Edit. Sorry after reading the comments I see that I need more of my code for this to make sense.
public function person($id)
{
$this->authenticate->check_access(array('admin', 'rps'), 'home');
$this->load->library('page_uri');
$this->load->model('term');
$this->load->model('user');
$this->load->model('id_conversion');
$selected_term = $this->page_uri->get_term();
$current_term = $this->term->current_term_id();
if (!isset($selected_term)) {
$selected_term = $current_term;
}
$term = new Term();
if (!empty($selected_term) && $selected_term !== '0') {
$term = new Term($selected_term);
}
$user = new User($id);
$plans = $user->plans_by_term($term);
$data = array();
$data['user'] = $user;
$data['site_url'] = site_url("reports/person");
$data['current_term'] = $this->term->current_term_id();
$data['selected_term'] = $selected_term;
$data['terms'] = $this->term->sorted_term_list();
$data['term'] = $selected_term;
$data['plans'] = $plans;
$data['outcomes'] = $this->id_conversion;
$this->load->view('template/foundation', $data);
}
the model id_conversion loads in
class Id_conversion extends MY_Model{
function __construct()
{
parent::__construct();
}
/*
* Input a primary or secondary outcome as defined
* in the plan class and
*/
public function id_outcomes($id)
{
$sql = 'SELECT name
FROM outcomes
WHERE id ='. $id;
$query = $this->db->query($sql);
return $query->row_array();
}
}
Using new will create a new object.
Using $this->id_conversion will use the existing object that was already created at some point previously and which was stored in that variable.
Without seeing more of your code, it's utterly impossible to know what state the existing object is in, so I can't tell you what difference it will make to create a new one compared with using the existing one. I would imagine there's a good reason for the program to have already created the object and stored it for you, so I guess it's been set up ready for use, but I can't tell for sure from what you've given us.
But even in the case that the existing object is in an entirely pristine condition and creating a new one would give identical functionality, you'd be wasting system resources in creating an extra object when one already exists. Only a small amount of wastage, to be sure, but it all adds up.
It's probably going to give the same results but not certainly.
If $this->id_conversion is a reference to a model class, that class may have been initialized in a different way. In Codeigniter, you can initialize an instance of a model like this:
$this->load->model('model_name', 'alias_name', $db_params);
If the class Id_conversion doesn't exist and id_conversion is actually an alias, then of course that wouldn't work.
If $db_params are different, then this is much different than just saying new Id_conversion();. Note also that the () are not needed if you aren't passing anything to the constructor. And as mentioned, it creates another unnecessary instance of the class.
And of course, if the state of $this->id_conversion has changed at all, for example:
$this->id_conversion->property = 'value';
...then it will not be the same at all.
Note that $this->id_conversion will be available in the view as well, so while it's probably good practice to explicitly pass it to the view, it isn't strictly necessary. The view runs in the same scope from the controller method that it was called in.
Better to stick to the Codeigniter way unless you are sure you know what you are doing.
I am trying to improve the method that I am using to to database transactions in a light framework I've built.
Information to understand the question:
Here's a class I've written (where connect.php loads up database credentials; a wrapper for the PHP PDO, stored in $db; and Base.php):
<?php
require_once('connect.php');
class Advertiser extends Base
{
public static function getByID($id)
{
global $db;
$sql = "SELECT * FROM advertiser WHERE advertiserid=?";
$values = array($id);
$res = $db->qwv($sql, $values);
return Advertiser::wrap($res);
}
public static function add($name)
{
$adv = new Advertiser(null, $name);
$res = $adv->save();
return $res;
}
public static function wrap($advs)
{
$advList = array();
foreach( $advs as $adv )
{
array_push($advList, new Advertiser($adv['advertiserid'], $adv['name']));
}
return Advertiser::sendback($advList);
}
private $advertiserid;
private $name;
public function __construct($advertiserid, $name)
{
$this->advertiserid = $advertiserid;
$this->name = $name;
}
public function __get($var)
{
return $this->$var;
}
public function save()
{
global $db;
if( !isset($this->advertiserid) )
{
$sql = "INSERT INTO advertisers (name) VALUES(?)";
$values = array($this->name);
$db->qwv($sql, $values);
if( $db->stat() )
{
$this->advertiserid = $db->last();
return $this;
}
else
{
return false;
}
}
else
{
$sql = "UPDATE advertisers SET name=? WHERE advertiserid=?";
$values = array ($this->name, $this->advertiserid);
$db->qwv($sql, $values);
return $db->stat();
}
}
}
?>
As you can see, it has fairly standard CRUD functions (Edit: Okay, so only CRU, in this implementation). Sometimes, I'll extend a class like this by adding more functions, which is what these classes are intended for. For example, I might add the following function to this class (assuming I add a column isBanned to the database):
public static function getBanned()
{
global $db;
$sql = "SELECT * FROM advertiser WHERE isBanned=1";
$res = $db->q($sql);
return Advertiser::wrap($res);
}
The question:
How can I create a catchall class that will also load up custom model classes when present and necessary?
For example, if I write the following code:
$model = new Catchall();
$banned = $model->Advertiser::getByID(4);
I would expect my catchall class to modify its queries so that all the references to the tables/columns are whatever name I chose (Advertiser, in this case), but in lower case.
In addition, if I wanted to create a custom function like the one I wrote above, I would expect my catchall class to determine that a file exists in its path (previously defined, of course) with the name that I've specified (Advertisers.php, in this case) and load it.
Advertisers.php would extends Catchall and would contain only my custom function.
In this way, I could have a single Catchall class that would work for all CRUD functions, and be able to easily expand arbitrary classes as necessary.
What are the ideas / concepts that I need to understand to do this?
Where can I find examples of this already in the wild, without digging through a lot of CodeIgniter or Zend sourcecode?
What is what I'm trying to do called?
General Stuff: I would look into Doctrine2 for examples of how they make an ORM in PHP. They use mapping in a markup language to say: this table has these columns of this type. Also, while not in PHP, the Django ORM is very easy to use and understand, and working through that tutorial for 20 minutes or so will really open your eyes to some neat possibilities. (it did for me)
A quick search for "php active record lightweight" returned several interesting examples that might start you down the right path.
PHP Ideas: I would look into the magic getter and setter in php, __GET and __SET that will let you set values on your objects without having to make a getter/setter for each field of each table. You could make a single __SET that will make sure that set field is a field in that table, and add it to the list of "fields to update" next time that object is saved. BUT, this is not really a good idea long term, as it gets out of hand quickly, and is brittle.
Advice: Lastly, I worked at a company that used a system that looks almost exactly like this, and I can say unequivocally, you do not want to try to scale this long term. A system like this (the active record pattern) can save massive amounts of time up front, by not having to write queries and things, but can cost tons down the road, if you ever want to start unit testing business logic on the object classes.
For example, it is not possible to mock/dependency inject that static GetById method (it is basically a global method), so every time that is called in code, the code will go to the real database and return a real object. It doesn't take much coding like this to make a system that is almost impossible to test, snarled and tightly coupled to the database.
While they can perform a little slower than your code above, if you are planning on having this around for a considerable amount of time, try looking into ORM tools.
Edit It's called Active Record.
There are a couple different design patterns for what you are trying to do. Look into Data Mapper and Active Record.
Using PHP's "magic method" __get, you can produce this functionality, when you access it via :
$model = new Catchall();
$banned = $model->Advertiser->getByID(4);
... it will a) check to see if the class Advertiser is already defined, b) check for a file called Advertiser.php and include it, or c) return a new instance of a generic class.
The syntax you used in your example with :: assumes that the returned class is static. I have not written this code to contend with that, but it should be trivial to do so.
See the docs: http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
Quick and dirty example:
public function __get($name) {
$instance = false;
// see if there is already a class with the requested name
if (class_exists($name)) {
$instance = new $name();
}
// check to see if there is an object def for the requested object
if ($instance === false && file_exists(PATH_TO_OBJECTS.$name.'.php')) {
require_once(PATH_TO_OBJECTS.$name.'.php');
$instance = new $name();
}
// if instace is still not found, load up a generic
if ($instance === false)
$instance = new Catchall($name);
return $instance;
}
I've just started using OOP PHP and ran into a question. I've set up a generic mysql class that allows me to connect to a database and has some functions to obtain records from a table:
class mysql{
//some lines to connect, followed by:
public function get_record($sql)
{
$result = mysql_result(mysql_query($sql));
return $result;
//obiously it's a bit more advanced, but you get the picture.
}
}
Next, I have a class to obtain user details:
class user{
__construct($id)
{
$this->id = $id
}
public function get_username($id)
{
$username = get_record("SELECT name FROM users WHERE id = '".$this->id."'");
return $username;
}
}
I tried this, but got the error that the function get_record was unkown. I solved this by adding $mysql = new mysql(); to the user class.
However, it feels quite inefficient to have to instantiate the mysql object for every class that uses my database methods (that's pretty much all of them).
Is there a way to make the mysql class and its methods accessible to all other classes, without having to call the mysql class in every method?
For one, you don't need to use singleton in this case - or actually, you almost never do. See this article, for example.
Second, I think your OO designs are a bit off. The main point of object-oriented programming and design is to isolate responsibility into separate classes. Right now, you're giving your User class two main responsibilities - store / carry one user's relevant data, and query the data service (in this case, a simple MySQL / database abstraction layer).
You should first move that functionality into a separate object. Usually, this is called a Service - so in this case, it's a UserService. A UserService has one responsibility: provide access to User objects. So it'd sorta look like this:
class UserService {
public function __construct($mysql); // uses the mysql object to access the db.
public function get($id) {
$result = $this->mysql->get_record("select x from y");
$user = new User($result['id'], $result['name']); // assuming user has a constructor that takes an id and a name
return $user;
}
public function save($user);
public function delete($user);
}
You tie it all together at the start of your request (or where you need to access users):
$mysql = new MySQL($credentials);
$service = new UserService($mysql);
$user = $service->find(1337);
It's not perfect, but it's a much neater design. Your MySQL object does what it needs to do (build a connection, execute queries), your user object is plain dumb, and your service does only one thing, i.e. provide a layer between the actual storage layer and the thing calling it.
Design your mysql class to be called statically:
$username = Mysql::get_record("SELECT name FROM users WHERE id = '".$this->id."'");
http://php.net/manual/en/language.oop5.static.php
This is a common problem, and so there is a common solution to this.
As you might know, in software development common solutions on common problems are called Design Patterns.
There are two design patterns that can help you solve this problem.
In a more abstract sense the problem you are facing is:
How can i make class A available in class B?
The Singleton pattern
"In the singleton pattern a class can distribute one instance of itself to other classes."
This is not exactly what you are looking for, as your website may use multiple database connections. However, it is used by a lot of people in this way.
Read some information about using a singleton class as a database provider here:
https://www.ibm.com/developerworks/library/os-php-designptrns/#N10124
More information on the singleton pattern in PHP:
http://www.fluffycat.com/PHP-Design-Patterns/Singleton/
Another sensible approach is the registry pattern:
Registry Pattern
You can find information about the registry pattern on the link below, as well as an implementation almost identical that you are looking for:
http://www.sitecrafting.com/blog/php-patterns-part/
Even more powerful is a combination between the singleton and the registry.
Good luck and enjoy learning OOP PHP!
You should pass in the mysql object to each user object. So it would look like this:
$mysql = new mysql();
$user = new user( $mysql, $id);
$name = $user->get_username();
class user {
public function __construct($mysql, $id) {
$this->mysql = $mysql;
$this->id = $id;
}
public function get_username() {
$username = $this->mysql->get_record("SELECT name FROM users WHERE id = '".$this->id."'");
return $username;
}
}
using global variables, although that is probably not the best option.
$mysql = new mysql();
function someFunction() {
global $mysql;
$mysql->get_record(...)
}
or a static method for your mysql class (see Singleton)
class mysql {
public static $theInstance = new mysql();
public static function getInstance() {
return $this->theInstance;
}
}
function someFunction() {
$database= mysql::getInstance();
$database->get_record(...)
}
Start to think to use Doctrine, it's better
http://www.doctrine-project.org/