Ok I am trying to start really learning OOP style in PHP. I have declared both interfaces and classes and have the classes implementing the interfaces. I was wondering however, is it not possible to just load interface files in into PHP script files and call the methods from the interface instead of loading the class implementation files? If so, how would that be done b/c I cannot find an answer to this. Thanks!
Interfaces can have no implementation, so you cannot do that. Their purpose is to stipulate "contracts" (in the sense that "classes that implement this interface promise to provide public methods X Y and Z") that the classes (which implement the interfaces) must honor.
This is really really basic OOP stuff, and it's not applicable to just PHP. I would suggest studying some more OOP theory before you try to progress further.
You cannot call methods on an interface. An interface cannot be instantiated. You must create a class that implements the interface and use that class instead.
An INTERFACE is provided so you can describe a set of functions and then hide the final implementation of those functions in an implementing class. This allows you to change the IMPLEMENTATION of those functions without changing how you use it.
For example: I have a database. I want to write a class that accesses the data in my database. I define an interface like this:
interface Database {
function listOrders();
function addOrder();
function removeOrder();
...
}
Then let's say we start out using a MySQL database. So we write a class to access the MySQL database:
class MySqlDatabase implements Database {
function listOrders() {...
}
we write these methods as needed to get to the MySQL database tables. Then you can write your controller to use the interface as such:
$database = new MySqlDatabase();
foreach ($database->listOrders() as $order) {
Then let's say we decide to migrate to an Oracle database. We could write another class to get to the Oracle database as such:
class OracleDatabase implements Database {
public function listOrders() {...
}
Then - to switch our application to use the Oracle database instead of the MySQL database we only have to change ONE LINE of code:
$database = new OracleDatabase();
all other lines of code, such as:
foreach ($database->listOrders() as $order) {
will remain unchanged. The point is - the INTERFACE describes the methods that we need to access our database. It does NOT describe in any way HOW we achieve that. That's what the IMPLEMENTing class does. We can IMPLEMENT this interface as many times as we need in as many different ways as we need. We can then switch between implementations of the interface without impact to our code because the interface defines how we will use it regardless of how it actually works.
Related
In my controller class I just want to use only one spreadsheet class to handle all the functions related to spreadsheet creation, save, load, write etc.
Currently I'm using one open source library phpspreadsheet to create a spreadsheet, if later I want to change that to another library of spreadsheet creation, I don't want to change much on the controller class, instead, I can create another class for this library, like Spreadsheetlib2. So which design pattern is better to use here? "Bridge" or Adapter?
// Bridge Pattern what I'm trying now.
interface SpreadsheetInterface {
public function create();
public function write();
}
class Spreadsheet extends AbstractSpreadsheet {
public function create() {
}
}
class PhpSpreadsheet implements SpreadsheetInterface {
public function create() {
}
}
abstract class AbstractSpreadsheet {
protected $spreadsheet;
protected function __construct(SpreadsheetInterface $spreadsheet) {
$this->spreadsheet = $spreadsheet;
}
}
I would really pay that much attention to "what pattern to use". Patterns are not magical recipes, to write your code by. They are just "shorthand descriptions", that you use to describe stuff you already wrote, to some other developer.
The way I would do it would be creating a wrapper (I think that counts as "adapter"), which implements some specific interface, that you Controller depends upon. And in this wrapper I would pass the PhpSpreadsheet instance as a dependency (or create a new instance of it directly in that wrapper).
When your controller calls a method on the wrapper, it forwards the call to the underlying "spreadsheet class.
Heres a little trick that Doctrine uses to define a Connection interface, while extending PDO at the same time.
interface Connection
{
public function prepare ($statement, array $driver_options = array());
}
class PdoConnection extends \PDO implements Connection
{
}
So, they wanted to define an interface that they could implement based on the requirements of whatever DB they were connecting to. But they wanted to keep the API pretty similar to PDO, however PDO doesn't implement an interface, so they had to piggy back one onto it by extending PDO while implementing Connection, therefore PDO unwittingly implements the methods of Connection.
You can do the same really. Choose whichever spreadsheet library you like best and create an interface from its methods, create a new class extending it then implement your interface.
Now when you want to switch implementation, your favourite library ought to have provided you with a decent amount of method signatures to implement another version.
I'm novice for PHP object Oriented Programming and confuse in following
i have a class "Customer" (customer.php) which has methods "display_registration_form()" and "add_cutomer()". the method "display_registration_form()" has code for the form to echo in order to display that form.
when user fills and submit that form, i need to send the data to "add_cutomer()" method which has SQL to add that data to the database.
but how to call that function? in procedural way it is easy to send data to the script where the method is defined and then call the method...but in this the script has a class!
so i think to define an other PHP script something "add_cutomer.php", instantiate an object from the class file, then call the method "add_customer()".
**form ----> add_cutomer.php <--------- customer.php (class)**
this solution learns me that in implementing OO in PHP, create the class file and create separate file(which is not a class just instantiate an object from the class) when using method of that class. May i know that, is it the correct way to implement or is there another if this is incorrect?
thanking you
regards
pradeep
Try this method:
customer.php
class Customer{
function display_registration_form(){
// Here is your function
}
}
callfunction.php
$db = new Customer();
$registration = $db->display_registration_form();
echo $registration;
You might want to read up on the basics of object oriented PHP programming using some of the free tutorials available throughtout the net. Here are a few a good places to start:
http://www.php.net/oop5.basic
http://www.tutorialspoint.com/php/php_object_oriented.htm
Wow, if you intend to code using OOP, a class method is not a good way to do it, it does not comply with MVC, also you can not manage the output format and the used theme.
However, this is a good thing to create and instantiate objects with this class.
You should understand there is 2 types of methods in OOP, the class methods and the instance methods, the first ones is also called static methods in PHP.
http://www.php.net/manual/en/language.oop5.static.php
Then, make sure you understand that instantiate a SQL object and create it very different, you will have 2 different static methods.
Finally, there are many PHP frameworks that implements OOP in a good way, i advise you to use one of them.
i have a service class written in php which called different classes to do same functions. In my each class, i am using the same functions for different clients. So every time a new client come to use my service, i just change the class name and the functions are remain same.
I have been trying to use the factory method pattern. But what i have figured out that if i use the factory method pattern, still i have to copy paste the same functions for different clients.
My scenario is i create a class to do the following.
For Client 1 functions are:
setClient()
process()
For Client 2 functions are:
setClient()
process()
I know i can use interface or abstract class. But still i feel there are some problems as the setClient() and process() functions do exactly the same things.
So what is the best approach to handle these type of scenarios?
I don't want to write or copy paste the same functions again and again in different classes for different clients for the same purpose.
advance thanks to all participants.
you can use an abstract class and then extend it in your client class. lets define the abstract class first.
abstract class base {
function common() {
echo "common code here";
}
}
then inherit it for each client.
class clienta extends base {
function clientAfunc() {
$this->common(); //call common
}
}
I'm building a class to handle Paypal IPNs as part of a project, and since I already know i'm going to need to use it again in at least two more upcoming jobs - I want to make sure I structure it in a way that will allow me to re-use it without having to recode the class - I just want to have to handle changes in the business logic.
The first part of the question is re. interfaces. I haven't quite grasped their usefulness and when/where to deploy them. If I have my class file ("class.paypal-ipn.php"), do I implement the interface in that file?
Here's what i'm working with so far (the function list is incomplete but its just for illustration):
CLASS.PAYPAL-IPN-BASE.PHP
interface ipn_interface {
//Database Functions
// Actual queries should come from a project-specific business logic class
// so that this class is reusable.
public function getDatabaseConnection();
public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb");
public function dbQuery($SQL);
//Logging Functions
public function writeLog($logMessage);
public function dumpLogToDatabase();
public function dumpLogToEmail();
public function dumpLogToFile();
//Business Logic Functions
private function getTransaction($transactionID);
//Misc Functions
public function terminate();
}
class paypal_ipn_base {
//nothing to do with business logic here.
public function getDatabaseConnection() {
}
public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb") {
}
public function dbQuery($SQL) {
}
}
CLASS.PAYPAL-IPN.PHP
final class paypal_ipn extends paypal_ipn_base implements ipn_interface {
//business logic specific to each project here
private function getTransaction($transactionID) {
$SQL = "SELECT stuff FROM table";
$QRY = this->dbQuery($SQL);
//turn the specific project related stuff into something generic
return $generic_stuff; //to be handled by the base class again.
}
}
Usage
In this project:
Require the class files for both the base, and the business logic class.
Instatiate *paypal_ipn*
Write code
In other projects:
Copy over the base IPN class
Edit/rewrite the business logic class *paypal_ipn* within the constraints of the interface.
Instantiate *paypal_ipn*
Write code
So as you can see i'm literally just using it to define groups of related functions and add comments. It makes it easier to read, but of what (if any) other benefit is it to me - is it so that I can pull the extender and the base class together and force errors if something is missing?
stdClass Question
The second part of the question is building on the readability aspect. Within the class itself there is an ever increasing number of stored variables, some are set in the constructor, some by other functions - they relate to things such as holding the database connection vars (and the connection resource itself), whether the code should run in test mode, the settings for logging and the log itself, and so on...
I had started to just build them as per usual (again, below incomplete & for illustration):
$this->dbConnection = false;
$this->dbHost = "";
$this->dbUser = "";
$this->enableLogging = true;
$this->sendLogByEmail = true;
$this->sendLogTo = "user#domain.com";
But then I figured that the ever growing list could do with some structure, so I adapted it to:
$this->database->connection = false;
$this->database->host = "";
$this->database->user = "";
$this->logging->enable = true;
$this->logging->sendByEmail = true;
$this->logging->emailTo = "user#domain.com";
Which gives me a much easier to read list of variables when I dump the entire class out as I code & test.
Once complete, I then plan to write a project specific extension to the generic class where i'll keep the actual SQL for the queries - as from one project to another, Paypal's IPN procedure and logic won't change - but each project's database structure will, so an extention to the class will sanitize everything back into a single format, so the base class doesn't have to worry about it and will never need to change once written.
So all in all just a sanity check - before I go too far down this road, does it seem like the right approach?
if you are using a class autoloader, which I highly recommend, you would not want to keep the interface and the class in the same file so that the interface can autoload without needing to first load this one class that implements it.
For more info on autoloading:
http://php.net/manual/en/language.oop5.autoload.php
another thing you may want to consider is that a given class may impliment multiple interfaces, and multiple classes may implement the same interface.
interfaces are primarily used for various design patterns, to enforce rules, and to decouple a class from any dependent classes. when you decouple a class from its dependencies, it makes it much easier to modify code at a later time.
for instance, let's say you have a class A that takes in another class B as an argument, and this class is spread throughout your code. you want to enforce that only a class with a specific subset of methods can be accepted as this argument, but you do not want to limit the input to one concrete class and it's decendants. in the future, you may write an entirely different class that does not extend class B, but would be useful as an input for class A. this is why you would use an interface. it is a reusable contract between classes.
some would argue that since PHP is a dynamic language, interfaces are an unecessary complication, and that duck typing may be used instead. I find in large multi-user code bases however, that interfaces can save a lot of time, letting you know more about how one class uses another, without having to study the code in depth.
if you find yourself with a large list of variables that you have to pass around between objects or functions, they often do end up deserving a class of their own, but each case is different.
-- dependency injection example --
class A implements AInterface {
public function foo($some_var) {}
}
interface AInterface {
public function foo($some_var);
}
class B {
protected $localProperty;
// inject into the constructer. usually used if the object is saved in a property and used throughout the class
public function __construct(AInterface $a_object) {
$this->localProperty = $a_object;
}
// inject into a method. usually used if the object is only needed for this particular method
public function someMethod(AInterface $a_object) {
$a_object->foo('some_var');
}
}
you can now see that you can write another class that impliments a foo method (and the AInterface) and use that within class B as well.
as a real world example (used often), say you have a database class with particular methods that interact with the database (getRecord, deleteRecord). now lets say at a later time you find a reason to switch database rdbms. you now need to use entirely different SQL statements to accomplish the same goals, but since you used an interface for your type hinting, you can simply create a new class that impliments that interface, but impliments those same methods in entirely different ways as it interacts with a different rdbms. when creating this new class, you will know exactly what methods need to be written for this new class in order to fit into the same objects that need to use a database object. if you use a container class that you use to create objects and inject them into other objects, you would not need to change too much application code in order to switch databases classes, and therefore switch database rdbms. you could even use a factory class, which could limit your changes to one line of code to make this type of change (in theory).
I'm creating a website with structure like this:
class main { }
class mysql extends main { }
class user extends main { }
class etc extends main { }
The idea is for these classes to use functions from each other. This doesn't work. How can I call a function from mysql in user?
EDIT:
All errors are similar to this one:
Fatal error: Call to undefined method user::function_in_mysql() in C:\foo.php on line 8
Martti Laine
The idea is for these classes to use functions from each other.
That's not what you're doing: Inheritance goes only one way. mysql, user, and etc inherit mains abilities but not those of each other.
You could have mysql extend user extend etc so that at least mysql can call all the functions but that probably won't make sense, as I think they are not ancestors but siblings to each other, fulfilling a distinctly different function.
You would have to either define any shared methods in main - often the best way to go - or introduce the classes to each other so they're able to call each other's functions. You could, for example, add an instance of each needed class as parameters to the constructor:
$etc = new etc();
$mysql = new mysql($etc);
// mysql's constructor sets $this->etc
// so that it can call etc's functions using $this->etc->function()
or, more complex, using the dependency injection or singleton patterns. I asked a related question some time ago about how to deal with this in PHP and got a lot of feedback, maybe it gives you some inspiration.
Having a class extend another makes the methods of the other (parent) available to it. So user extending main only makes the methods of main available to it. If other classes extend main it doesn't allow all of them to call each others methods. You could have user extend mysql and mysql's methods would then be available to user though I don't believe that fundamentally this is what you're looking for.
I think you're looking for something along the lines of dependency injection and not class inheritance.
For example if you wanted your user class to have access to your mysql class you pass it an instance of it in it's constructor.
class user {
protected $_mysql;
public function __construct(mysql $mysql) {
$this->_mysql = $mysql;
}
public function myMethod() {
$this->_mysql->myMysqlMethod();
}
}
$mysql = new mysql();
$user = new user($mysql);
$user->myMethod();
Here's some good reading on dependency injection.
PHP Dependency Injection
Symphony Dependency Injection
The Symphony link in particular is a pretty nice read on the overview of dependency injection and how to setup a dependency container.
That's not how extending a class works. All the functions that should exist in all classes should be part of main. Then functions that are specific to mysql go in that class. I'm guessing that the classes are not as closely linked in terms of inheritance as you think. If the user class needs to make calls through your mysql class, have a variable in the user class that holds a mysql object.
To call a function from mysql inside of user you could create an mysql object inside of user and call the function.
<?php
// this is user.php
$var = new mysql(); // <--if it takes parameters in the constructor
$var->method();
...
?>
For a better answer could you provide more information, as in, what errors are you getting?