I have class, where i make connection to database and do some queries.
But i can't make query to this database from other class. Problem is that class Cd can't see db connection command -> can't make a query. Here is the code:
require_once('config.php');
class myClass
{
public $mysqli;
public $res;
function connect()
{
$database = new Database();
$this->mysqli = new mysqli($database->db_host, $database->db_user, $database->db_pass, $database->db_table);
}
function cd($id)
{
......
}
}
}
class Cd extends myClass
{
function cdname($id)
{
$get= new Scandiweb();
$get->mysqli;
$this->res = $get->mysqli->query("SELECT * FROM disk WHERE id=" . $id . "");
if ($this->res->num_rows > 0) {
.........
}
}
}
Your code is a bit messy, so it's hard to tell where exactly the problem lies:
Why do you require config?
Why do you create a Database (which is more like a DbConfig) in the constructor instead of passing it?
What is the Scandiweb-class?
Why do you call mysqli->query on that class instead of $this
The last one is your immediate mistake. You extend myClass which creates the mysqli-connection and stores it as class variable $this->mysqli. That means that the child class Cd will have access to it. When you extend a class you can call all it's public and protected properties and methods. Only those marked as private can't be accessed.
That means instead of accessing $get->mysqli->query(...) you can do $this->mysqli->query(...). What would make sense in OOP is to create a connection once (like you do in the constructor) and pass it around to the services requiring a database connection. This is called Dependency Inversion Principle and using a Dependency Container makes it easier (but is not mandatory).
There are so called design patterns that will make it easier to deal with performing sql queries like in your code above. The most common ones are the Active Record-pattern as used in Laravel's Eloquent and the Propel library, the Table Data Gateway-pattern as used in Zend Framework's DB-component and the Data Mapper-pattern as employed by Doctrine ORM. If you want to write OOP code you should look at their documentation and maybe use one of those instead of dealing with everything yourself.
Related
In PHP, I have two classes: Database and Item.
Database contains the connection properties and methods. For example, Database::Query can be used to pass a query string, etc.
Item is a generic item identifier. It's built by passing it an itemID which is then used to query the database for the rest of the item information.
In this case, what's the best practice for creating Item objects if they require database access? Is it normal to create each one using this syntax:
$item = new Item(12345, $db);
Or is it better, acceptible, or possible to create the Database object and have it used for each Item created in the application, such that the call could become:
$item = new Item(12345);
The second seems a lot cleaner (and can be expanded so that similar types of objects don't also need that $db addon), but I'm looking for suggestions from those who have more experience at this than I do! Thanks!
I would suggest that most seasoned developers would lean toward the approach of dependency injection as demonstrated in your first example.
Why?
Well largely because this allows you to decouple the class to which the dependency is being injected from the dependency's implementation.
So consider this dependency injection example:
Class some_class {
protected $db;
__construct($db) {
if($db instanceof some_db_class === false) {
throw new Exception('Improper parameter passed.');
}
$this->db = $db;
}
}
Here you could pass any type of object so long as it was an instance of some_db_class it could be a subclass of that object that implements the same methods used by this class. That doesn't matter to this class as long as the methods are implemented (you of course could also check that a passed object implements a specific interface in addition to or in lieu of checking its instance type).
This means that, for example, you can pass a mock DB object for testing or something like that. The class doesn't care as long as the methods are implemented.
Now consider the singleton approach (or similar instantiation of DB from with the class):
Class some_class {
protected $db;
__construct() {
$this->db = some_db_class::get_instance();
}
}
Here you have tightly coupled your class to a specific database class. If you wanted to test this class with a mock DB implementation it becomes very painful in that you need to modify the class to do so.
I won't even get into discussion of using global as that is just poor practice and should not be considered at all.
I would recommend using the Singleton Pattern for your database connection. This is actually the best practice. As you really dont need to instances of your database connection.
class Database_Instance
{
private static $database;
public static function getDatabaseObject() {
if (!self::$db) {
self::$db = new PDO( );
}
return self::$db;
}
}
function callWhatSoEver()
{
$connection = Database_Instance::getDatabaseObject();
}
For more information about the singleton pattern, see: http://en.wikipedia.org/wiki/Singleton_pattern
Typically a database connection object is global, or accessible globally. That works well for the vast majority of applications.
I do something like this (simplified for example purposes):
$db = connect_to_db();
function GetDB()
{
global $db;
return $db
}
//inside the item object
function Load( $id)
{
$db = GetDB();
$db->query(..);
}
There are, of course, cases where this isn't the best route. As always, it depend on the specific needs of your application.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class. But the problems is I want to create only single instance of MyApplicationBase. Below is the code which explains what I mean
class MyApplicationBase{
static $called=0;
public var $db;
function __construct()
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db=new DatabaseWrapper();
}
}
class ApplicationSecurity extends MyApplicationBase{
function is_logged_in()
{
$res=$this->db->query("user check db query goes here");
return ($res)?true:false;
}
//..... other methods related to ApplicationSecurity class
}
class ApplicationBusinessLogic extends MyApplicationBase{
// business logic methods here which may use base class vars like $db
// this may also use instance of ApplicationSecurity class
}
class ApplicationTemplating extends MyApplicationBase{
protected function outputHeader()
{
require_once('path/to/themes/header.php');
}
protected function outputSidebar()
{
require_once('path/to/themes/siderbar.php');
}
protected function outputMainbody()
{
require_once('path/to/themes/mainbody.php');
$app=new ApplicationBusinessLogic();
$app->initiate();
}
protected function outputFooter()
{
require_once('path/to/themes/footer.php');
}
public function outputTemplate()
{
$this->outputHeader();
$this->outputSidebar();
$this->outputMainbody();
$this->outputFooter();
}
}
//index.php file code starts here--------
$myPhpApplication = new ApplicationTemplating();
$myPhpApplication->outputTemplate();
My goal is when I create instance of my application then It only call the single instance of "MyApplicationBase" class instead of calling it multiple times. Please do tell me how can I achieve this. I am google for 5 hours but unable to find any solution yet.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class.
As PHP has single inheritance, this is by far the most worst idea to do object oriented PHP programming.
But the problems is I want to create only single instance of MyApplicationBase.
As every class is a MyApplicationBase you actually don't want that because it would mean you could instantiate exactly one class in your whole application.
What you're probably looking for is some kind of ApplicationClass which you pass along and of which just a single instance exists.
This would at least allow you in the future to throw such a "block in road" away more easily then if you would have got extended from there.
In any case you should program against an ApplicationInterface instead of an ApplicationClass to make this throwing away - as it will be necessary - easier.
The best thing for sure would be to not do anything in that direction and only write code you need in the first place.
To only write code you need, you need to develop test-driven. Why not start with that if you want to do object oriented programming?
Well I suppose that you want to avoid multiple connections to the database in this case. Solution is simple with Dependency injection, just initialize your database connection outside of MyApplicationBase class and then pass it as a constructor parameter (beware of constuctor hell though). Like this:
class MyApplicationBase{
static $called=0;
public $db;
function __construct($db)
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db= $d;
}
}
$db = new DatabaseWrapper();
$templating = new ApplicationTemplating($db);
$security = new ApplicationSecurity($db);
You could also take a look at some framework, they usually come with some dependency injection capabilities.
So I know that questions with 'what is the best' in their title aren't supposed to be asked, but really.. how should you do this?
We have a database class and, for example, a user class. A user class will get methods such as create() and update(), which will need to do database stuff.
As far as I know there are 2 main options, passing on the database object in every __construct() or make the database class static.
(Any other tips about OOP + database driven websites are also appreciated)
A very common pattern here is to make the database class a singleton construct, which is then passed to every object constructor (that is called Dependency Injection).
The purpose of making the database object a singleton is to ensure that only one connection is made per page load. If you need multiple connections for some reason, you would want to do it a different way. It's important to pass it via the constructors though, rather than creating the database object inside an unrelated class so that you can more easily test and debug your code.
// Basic singleton pattern for DB class
class DB
{
// Connection is a static property
private static $connection;
// Constructor is a private method so the class can't be directly instantiated with `new`
private function __construct() {}
// A private connect() method connects to your database and returns the connection object/resource
private static function connect() {
// use PDO, or MySQLi
$conn = new mysqli(...);
// Error checking, etc
return $conn;
}
// Static method retrieves existing connection or creates a new one if it doesn't exist
// via the connect() method
public static function get_connection() {
if (!self::$connection) {
self::$connection = self::connect();
// This could even call new mysqli() or new PDO() directly and skip the connect() method
// self::$connection = new mysqli(...);
}
return self::$connection;
}
}
class Other_Class
{
// accepts a DB in constructor
public function __construct($database) {
//stuff
}
}
// Database is created by calling the static method get_connetion()
$db = DB::get_connection();
$otherclass = new Other_Class($db);
// Later, to retrieve the connection again, if you don't use the variable $db
// calling DB::get_connection() returns the same connection as before since it already exists
$otherclass2 = new Other_Class(DB::get_connection());
Another method is to create your database class directly extending either mysqli or PDO. In that case, the __construct() method supplies the object to getConnect(), as in
public static function get_connection() {
if (!self::$connection) {
self::$connection = new self(/* params to constructor */);
}
return self::$connection;
}
Well, what you can do is to have the database access layer in one object, which is then passed to your objects, respecting the inversion of control pattern.
If you want to dig a bit into this direction, have a look into dependency injection (DI): http://en.wikipedia.org/wiki/Dependency_injection
Having a singleton is usually a bad idea as you will end up having problems when testing your code.
Having the database access logic within a model class such as User violates the separation of concerns principle. Usually DAO (Data Access Object) handles db related concerns.
There are ORM frameworks such as Hibernate, which handle mismatch between OO and relational models quite well, potentially saving a lot of manual work.
I'm really surprised that no one said this, but here it goes: ORM.
If your weapon of choice is PHP, then the major options are Propel and Doctrine. They both have many strengths and some weaknesses, but there's no doubt that they're powerfull. Just an example, from Propel's (my personal favourite) user manual:
// retrieve a record from a database
$book = BookQuery::create()->findPK(123);
// modify. Don't worry about escaping
$book->setName('Don\'t be Hax0red!');
// persist the modification to the database
$book->save();
$books = BookQuery::create() // retrieve all books...
->filterByPublishYear(2009) // ... published in 2009
->orderByTitle() // ... ordered by title
->joinWith('Book.Author') // ... with their author
->find();
foreach($books as $book) {
echo $book->getAuthor()->getFullName();
}
You won't get more OO than that!
They will handle a lot of things for you like for one, abstracting your data from the database vendor. That said, you should be able to move (relatively painlessly) from MySQL to SQL Server and if you're building your own tools for web applications, then beign able to adapt to different environments is a very important thing.
Hope I can help!
Hey have a look at ORM's. Let them do the hard work for you? fluent nhibernate or microsofts entity framework.
I could be misunderstanding your question. Sorry if so
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/
I have a custom database class that I wrote myself, and I also have a user class and a site class.
The MySQL class has methods like this:
connect
query
clean
fetch
The user class:
register
login
logout
resetPass
The site class:
updateTopics
addTopic
addPost
addReply
etc.
These classes need to interface with a database, which is what I wrote the MySQL class for. But, I have no idea how to properly use the MySQL class with these classes. Do I define the class as global and just reference it in the other classes? Do I do something like:
$db = new MySQL();
$user = new User($db);
and then reference it like that?
Any help is appreciated, thank you. :)
In addition to Daniel Vandersluis's answer:
Instantiating the object within your class creates a strong dependency between those classes. You might instead be interested in dependency injection and inversion of control (+ ioc containers).
see:
http://en.wikipedia.org/wiki/Dependency_injection
http://martinfowler.com/articles/injection.html
btw: Do you really need your own MySQL class implementation? There are already so many database access and abstraction layers available. E.g. http://docs.php.net/pdo.
you might be interested in stantiating the MySql class just one time. it prevents the connection to be opened and closed many times during execution. i like to use the Factory concept. it's a class that handle the instantiation of objects and you can write it to allow only one instance, following the Singleton concept.
someting like this:
class Factory {
private static $objects = array();
static function get_database() {
if( ! isset(self::$objects['database']))
self::$objects['database'] = new MySql();
return self::$objects['database'];
}
}
you would use like that:
$db = Factory::get_database();
note that it always return the same instance of MySql instead of creating new ones.
well, but it's just a very simple implementation of a Factory, just for understanding. it could be a lot better =]
You could instantiate your MySQL class within your other classes, like so:
class User
{
private $db;
function __construct(...)
{
$this->db = new MySQL();
}
function accesses_database(...)
{
$this->db->query(...);
}
}
And then reference $this->db inside your class when you want to access the database.
Also, if you want there to only be one instantiation of MySQL, you can make it a singleton.