Im having a hard time grasping this concepts of objects and how they should interact/exist.
Should I for instance have different objects (well, maybee I mean connections to the database here if there is any difference) for interactions with my database whenever they are not related?
Lets say I have one object that index.php uses to get and display content from the database
and another object that a user use to add/remove things in the database. We can say that the objects are all of the class dbinteract which holds all the functions for messing about with the database.
Or should I maybee divide the classes into something like: dbconnection, dbdisplay, dbinsertion, dbmodification where I send the dbconnection to the other objects?
I feel like im missing something very obvious and it's frustrating trying to move forward not knowing where in the thought process im going wrong, I guess im looking for a question as well as a an answer here.
index.php
$connection = new dbconnection();
$displayer = new dbdisplay();
$activeconnection = $connection->connecttodatabase();
$pagetodisplay = $connection->getcontentofpagetodisplay($query);
$displayer->displayPage($activeconnection, $pagetodisplay);
userinsert.php
$inserter = new dbinsert();
$usersdbconnection = new dbconnection();
$inserter->newPost($userdbconnection, $usercredentials, $posttextfromuser);
$usersdbconnection->closedatabaseconnection();
You seem to be think at the wrong level of abstraction. OOP allows you to think about 'users' and 'articles' instead of 'database connections' and 'pages'.
I'm not sure I understand the problem fully - I think your question is 'which object should be responsible for connecting to the database?'. Creating a connection to the database only needs to be done once. This connection can then be shared between all of the objects. To share the connection you will need to create a class which all other classes that connect to the database can inherit from and a static variable in that class to ensure that only one connection object exists.
In other languages static variables are commonly called class variables.
To me, what it seems like you're missing is that object-oriented programming isn't there to make you do extra work following its rules, it's there to make your life easier. If it isn't making your life easier, you're doing it wrong.
sometimes books are better then surfing the net
i found this book really useful.
the examples lean towards java, but can be applied to any language
http://oreilly.com/catalog/9780596008673/
Related
Another question trying to verify the understanding of OOP dependencies of classes.
Although I knew PHP 4.* quite well, I have only recently restarted programming, and thus started working on OOP so please be gentle ;)
Classes should be as independent as possible I understand. So, when I have a class institute that gets information from a database, I would have to inject institute with an instance of the database class, right?:
$dbh = new database();
$a = new institute();
$a->SetDBI($dbh);
In database, I have a method pulling one record from the database, and is fed with the table table, the ID column and the actual ID of the record to be pulled.
Now, say I want one method in Institute that gets one institute. To me it would make sense to then use the database class method getone():
public function GetInstitute()
{
$record = $this->dbi->GetOneRecord('table', 'column', $this->id);
}
Is this the right way of going about it? It feel that I am still building dependencies between classes this way?
The question is: am I building dependencies that should not be here? Or is it standard practice to use methods from one class in another class, as shown in the example?
This is right. You still have some dependencies between classes, but only to a certain degree. Actually (because of PHP's weak typing), you can pass any class, and it will work as long as it implements the GetOneRecord method properly.
To make it a little more strict, you can use a base class or an interface and add type hinting to the setDBI method, but otherwise, this is the way to go.
But for the implementation detail, I'm not so sure. I see you pass a table name and column name to the database object. That is not right. You don't want your Institution to know how and where it is saved. I'd rather see that you passed an object implementing a LoadInstitution($id) method. But I find it hard to give you a solid example, because it's unclear to me what GetInstitute is meant to do in the first place.
Hello i have a code where they use this to connect to database
$db= DAL::get_instance();
$count=$db->read_single_column("select count(id) from ".TABLE_PREFIX."users where email=? and status=1", array($email));
echo "Aqui".$count;
I make a blank new page for that site, but i think $db= DAL::get_instance(); is not working.. i dont want to create multiple Connections to database, so how can i use DAL on PHP so i can use that same chain to connect...
And where and how is set DAL? (how can i search for the string where is set, whats the format)
Thanks
I Found a DAL.php on the library core.. But its encripted with Ioncube.. so my guess is i wont be able to see how is set :(
Your DAL class is userland-defined - there is no such thing in PHP. Post the entire code of it somewhere and someone might be able to tell you what to do with it.
I will, however, provide generics based on what you've said. static::get_instance() and the mention that you are not able to fire more than one instance of it suggests that your database abstraction layer is, in fact, a Singleton. This is good, and then again, this is very bad. The entire aim of the Singleton is to restrict the class to one and one instance only, which is quite nice for a database layer.
In your case, however, it looks like you want to connect to multiple DBs at the same time. Depending on how the code is coded, you may be able to do this with little to no modification to the code.
For reference, this is a simplified version of your DAL: http://codepad.viper-7.com/gPQ8bo . I kept the bits you are concerned with and stripped everything else out.
The obvious way
Rip up the singleton and start using dependency injection.
The not-so-obvious way
You can use Reflection to reset a Singleton's private static member. This is a hack, so use only if you have to.
The fiddle to this lies here: http://codepad.viper-7.com/ja6zHL . The code is as follows:
$reflection = new \ReflectionProperty('MySingleton', 'instance'); // Get a handle to the private self::$instance property
$reflection->setAccessible(true); // Set it to public
$reflection->setValue(null, null); // Modify it
// Optional: re-restrict it
$reflection->setAccessible(false);
Note that this is hackish for three reasons:
You should not be doing this. Instead, you should consider using a DAL that actually allows you to fire multiple connections or make one yourself
This uses Reflection, which has pretty big performance implications
This is a hack. You also lose your first DB connection, so you need extra housekeeping.
I am playing around with OOP programming, and have hit a hurdle I could use advice with.
I have a situation where I have nested classes. I have a "Company" class, which contains an array called people. This array contains many instances of a "Person" class.
The data for both 'company' and 'person', are stored within a database, and the relevant class retrieves the information from that database as and when it is needed.
My question quite simply is this: "At what point do I connect to the database?" Do I:-
a) Connect first in my PHP page, then pass the connection to the instance of "Company" for it to use.
b) Put the username, password etc directly in the "Company" class and connect there.
I would have thought that the latter would create multiple connections to the database - one for each instance of "Company" - so probably the answer is "A". But then, if I were to pass the class to another developer (this is only a learning exercise, so not something I plan to do), he would have to connect to the database himself, and not allow my class to do it for him.
In either case, would the connection be passed to each instance of the "Person" class automatically, or would I have to pass the connection each time I create a new instance?
I have done some research on this, and I think the answer is "A" (connect to the database in my PHP page, and pass the connection to each instance of the Company class), but just thought I should double check before I get too far.
Thanks for any advice you are able to offer.
You solution A) sounds familiar to me. That way you can just pass the database connection to the object or maintain a global registry to store the connection object (e.g. PDO) into.
I think you're on the right track.
What you're describing is known as dependency injection and using it is generally a good idea.
When you're dealing with a more complex project, it might be a good idea to abstract the retrieval of data completely. Create an interface, i.e. "PersonFinder" or "CompanyFinder" that deals only with the lookup and retrieval of its associated records. Concrete implementations of this interface might include database lookups, or CSV file lookups, or even some sort of web-based service lookup. Pass your Finder into your Company or Person objects when you create them.
This way you can easily change how you find your records without changing the code that deals with them.
This is going to take a bit to explain. I'm creating my first real-world web application, and I'd to do it properly. I have very little PHP experience, but vast experience in other languages so technical skill isn't a problem, it's more conventions of the language. I'm following the MVC pattern, and I am at the stage where I'm implementing user registration for the application.
To standardise connections to the database, I've created a Config class with a static getConnection method, which creates a mysqli connection object. This isn't a problem, it's the next bit that is.
To make my classes a bit more readable, I have various functions built into them that make database calls. For example, my User class has a getFriends method like so:
class User
{
public $id;
public getFriends()
{
return UserController::getFriends($id);
}
}
But as it stands now, if I implement it that way, it means creating a connection for every query on a page, probably many times in a single script, which is just horrific.
I was thinking about doing the same as above, but pass getFriends a mysqli object, which in turn passes one to UserController::getFriends as well, but that feels messy, and frankly poor form, even though it would guarantee only one connection per script, a much better improvement.
I also thought about scrapping the idea of keeping the methods inside User altogether, and instead making calls like UserController::getFriends($connection, $id) directly in the script, with a single $connection declared at the beginning, in place of user->getFriends(). That seems like the absolute cleanest, nicest solution, but I'm unsure.
So, essentially, how do PHP folks normally do this sort of thing?
What I do in my MVC framework is create a db connection and assign it to the Model base class (in the config):
$db = new database\adapters\MySQL(...);
if ( !$db->connected() ) {
exit('Ewps!');
}
database\Model::dbObject($db);
Then later on, anywhere, I can use:
User::getFriends(13);
because User extends Model and Model has access to $db: self::dbObject()
If I need my raw db connection, I either use Model::dbObject() or $GLOBALS['db'], but I rarely do need the raw connection, because all db logic should be in your Models.
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/config/database.php
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/models/User.php#L30
Have a look into the Singleton Pattern . It allows you to create a class (a DB object), but where only one of them is ever allowed (so more than one can't be instantiated).
This means that you only have to create one connection to the DB and it's shared.
Check here for a code example
Accoring to the Symfony 2 Documentation, you have to use the following PHP code to connect to the database and execute a query...
$conn = $this->get('database_connection');
$users = $conn->fetchAll('SELECT * FROM users');
I'm a complete novice with Symfony 2 but I am experienced with OOP. I was wondering if it was possible to have a globally available $conn variable that I can access from any bundle. The $conn variable would contain the value of $this->get('database_connection') so I don't have to retype $conn = $this->get('database_connection');it every time I want to make a new query.
Thanks!
global variables are most of the time NOT something you want in OOP. They are confusing when it comes to a method which deals with multiple variables and they might even be hidden by local variables. For me, working with statements like
$anything = $this->get('what.the.hell.why.arent.those.identifiers.shorter');
is as annoying as for you so I ended up in creating one subclass of Symfony\Bundle\FrameworkBundle\Controller\Controller per project which provides methods which call get with the actual identifiers. In your case I would create a method
public function getDatabaseConnection()
{
return $this->get('database_connection');
}
In general - why don't you use Doctrine for managing the DB connection? Most of the queries can be done by the ORM and this is the way to work with a real object-oriented interface to the database. Think about it, I'm also playing with Symfony2/Doctrine since some days and it really feels good. In the beginning, it might look like a hell of configuration, but once you've done the basic configs, the development is really fast! :)