I have a class wrapper, class car, that lives in the namespace of Automobile. Then I have class tire that lives in the namespace of Automobile\Wheels. In the tire class, I want to access a static variable from the car class, but the only way to do that is to reference the complete namespace\class.
<?php
namespace Automobile;
class Car {
public static $Axle;
public function __construct() {
static::$Axle = new Axle();
}
}
<?php
namespace Automobile\Wheels;
class Tire {
public $size;
public function __construct($size = 16) {
$this->size = $size;
\Automobile\Car::$Axle->add_wheel($this);
}
}
My questions are: is it an okay practice to reference classes like this? Are there any ways to reference the class without including the complete and absolute namespace for the class?
There's really no good or bad way to do it, although people might be quite opinionated about it (the same with using spaces or tabs for indents, but let's not go down that road ;) ). As long as they're properly referenced it's okay to use fully qualified class names.
You might want to use the use keywords to 'import' external classes, which improves the readability in my opinion:
<?php
namespace Automobile\Wheels;
use Automobile\Car;
class Tire {
public $size;
public function __construct($size = 16) {
$this->size = $size;
Car::$Axle->add_wheel($this);
}
}
You might want to reference the PHP documentation, as it is quite concise about the subject and gives good insight in how to use namespaces.
As others have pointed out, use use for the full namespaced class (e.g., use Automobile\Car;). From there, you can use the shortened class reference (e.g., Car) throughout the rest of the file.
As an aside, it's best practice to avoid statically invoking properties and method if at all possible. It's generally considered best practice to inject your dependencies as it decouples your code and allows for swapping out of pieces of your application using interfaces.
I would do something like this:
<?php
namespace Automobile;
class Car {
/** #var Axle */
public $axle;
public function __construct(Axle $axle) {
$this->axle = $axle;
}
}
<?php
namespace Automobile\Wheels;
use Automobile\Car;
class Tire {
public $size;
public function __construct(Car $car, $size = 16) {
$this->size = $size;
$car->axle->add_wheel($this);
}
}
Related
I want to make a PHP class, lets say Myclass.php. Now inside that class I want to define just the class itself and some instance variables. But all the methods must come from a Myclass_methods.php file. Can I just include that file into the class body?
I have good reasons why I want to seperate this. In short, I'll have a backend in which I can change the business logic of a class, while all other things must remain untouched. The system maintains all the ORM and other stuff for me.
But if this is a bad idea, it might be better to re-generate the whole class file after editing the business logic (so, the user-defined methods in this case).
Performance question: If during one request Myclass.php is included just once, actually that Myclass_methods.php should also be included just once. Might be wrong. Experts?
No. You cannot include files in the class body.
In a file defining a class, you may only include files in a method body or outside the class body.
From your description I take you want this:
<?php // MyClass.php
class MyClass
{
protected $_prop;
include 'myclass-methods.php';
}
<?php // myclass-methods.php
public function myMethod()
{
$this->$_prop = 1;
}
Running this code will result in
Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION
What is possible though is this
<?php // MyClass.php
class MyClass
{
protected $_prop;
public function __construct() // or any other method
{
include 'some-functions.php';
foo($b); // echoes 'a';
}
}
<?php // some-functions.php
$b = 'a';
function foo($str)
{
echo $str;
}
Doing it this way, will import the contents of the include file into the method scope, not the class scope. You may include functions and variables in the include file, but not methods. You could but should not put entire scripts into it as well and change what the method does, e.g.
<?php // MyClass.php
// ...
public function __construct($someCondition)
{
// No No Code here
include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php';
}
// ...
<?php // whatever.php
echo 'whatever';
<?php // default.php
echo 'foo';
However, patching the class this way to exhibit different behavior is not how you should do it in OOP. It's just plain wrong and should make your eyes bleed.
Since you want to dynamically change behavior, extending the class is also not a good option (see below why). What you really will want to do is write an interface and make your class use objects implementing this interface, thus making sure the appropriate methods are available. This is called a Strategy Pattern and works like this:
<?php // Meowing.php
interface Meowing
{
public function meow();
}
Now you got the contract that all Meowing Behaviors must obey, namely having a meow method. Next define a Meowing Behavior:
<?php // RegularMeow.php
class RegularMeow implements Meowing
{
public function meow()
{
return 'meow';
}
}
Now to use it, use:
<?php // Cat.php
class Cat
{
protected $_meowing;
public function setMeowing(Meowing $meowing)
{
$this->_meowing = $meowing;
}
public function meow()
{
$this->_meowing->meow()
}
}
By adding the Meowing TypeHint to setMeowing, you make sure that the passed param implements the Meowing interface. Let's define another Meowing Behavior:
<?php // LolkatMeow.php
class LolkatMeow implements Meowing
{
public function meow()
{
return 'lolz xD';
}
}
Now, you can easily interchange behaviors like this:
<?php
require_once 'Meowing.php';
require_once 'RegularMeow.php';
require_once 'LolkatMeow.php';
require_once 'Cat.php';
$cat = new Cat;
$cat->setMeowing(new RegularMeow);
echo $cat->meow; // outputs 'meow';
// now to change the behavior
$cat->setMeowing(new LolkatMeow);
echo $cat->meow; // outputs 'lolz xD';
While you also could have solved the above with inheritance by defining an abstract BaseCat and meow method and then deriving concrete RegularCat and Lolkat classes from that, you have to consider what you want to achieve. If your cats will never change the way they meow, go ahead and use inheritance, but if your RegularCat and Lolkat is supposed to be able to do arbitrary meows, then use the Strategy pattern.
For more design patterns in PHP, check these resources:
http://www.php.net/manual/en/language.oop5.patterns.php
http://www.ibm.com/developerworks/library/os-php-designptrns/
http://www.fluffycat.com/PHP-Design-Patterns/
http://sourcemaking.com/design_patterns
Might it not be an idea to create the core class with the relevant base functionality and then extend this with the required methods - it seems like a more logical approach.
I'll start by saying I'm not too clear why this problem is not best solved using a base class containing the methods, subclasses containing the data, and dynamic class loading. I'll assume you have a good reason.
Once your provider supports PHP 5.4 you can do what you want using traits.
Code File:
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');
class Pet {
use PetSounds;
}
$myPet = new Pet();
$myPet->speak();
File cat.php
trait PetSounds {
function speak() { echo 'meow'; }
}
File dog.php
trait PetSounds {
function speak() { echo 'woof'; }
}
You could make this even cleaner by naming both include files the same, putting them in different subdirectories, and using set_include_path() or defining an __autoload() function to select between them. Like I said though, this same problem could be solved better using inheritance. If you have a multiple-inheritance type problem though, if for instance you have four kinds of pets with five kinds of colors with three hair types and you need a different combination of methods for each of the 60 different classes, this is the right solution.
5.4 is currently just a Release Candidate (as of 2/24/2012) and even once released most hosts will not support it for many months - mine took 18 months after 5.3 was released before they would support it. Until then you must write entirely separate and complete class files. You can however format your classes with an eventual change to traits in mind.
Right now you can partially get what you want using magic methods and have an easy upgrade to traits when they are available.
Code File:
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');
class Pet {
public function __call($name, array $arguments)
{
array_unshift($arguments, $this);
return call_user_func_array("TraitFunc_$name", $arguments);
}
}
$myPet = new Pet();
$myPet->speak();
File cat.php
function TraitFunc_speak(Pet $that) { echo 'meow'; }
File dog.php
function TraitFunc_speak(Pet $that) { echo 'woof'; }
You are limited however in that your functions can not access private and protected class properties and methods and you can not use this method to provide magic methods such as __get(). Traits will solve both of those limitations.
What about using traits for this? Would that be an acceptable option? This is something I am currently experimenting with and it seems to work quite while.
A simplified version of what I am doing is basically like this. I have an application with shared core files and multiple projects. Within those projects i have modules. I want to have functions that are available for the entire project on a core level but only for that specific project.
My project controller
if(is_file(PROJECT_PATH.'/project_extensions.trait.php')){
// additional functions for this specific project
require_once(PROJECT_PATH.'/project_extensions.trait.php');
}else{
// no additional functions
trait Extensions{};
}
Class Project{
USE Extensions;
// default functions shared between all projects
function shared_stuff(){
}
}
Extensions file
trait Extensions{
// project-specific extensions
function this_project_only(){
echo 'Project Only';
}
}
Module file in the project
class MyModule extends Modules{ // modules extends projects in a different class not relevant here
function do_something(){
echo $this->project_only();
}
}
Since PHP5.4 release you can create dynamic objects like this: https://github.com/ptrofimov/jslikeobject
But this is scarcely the best practice.
Reviving an old question but this is a fairly simple solution. Do you need the common function calls to be exclusive to your class? If not, simply include your common function file(s) within the same scope as your class. You will need to create methods in your class but they will only need to call the common function. Here's a simple SOAP server example:
<?php
include 'post_function.php';
$server = new SoapServer( null, array('uri' => "http://localhost/") );
$server->setClass( 'postsoapclass' );
$server->handle();
class postsoapclass
{
public function animalNoise( $animal )
{
return get_animal_noise($animal);
}
}
?>
post_function.php
<?php
function get_animal_noise($animal)
{
if(strtolower(trim($animal)) == 'pig')
{
return 'Oink';
}
else
{
return 'This animal is mute';
}
}
?>
I have had to do what you are describing in cases where I maintain a free version and a premium version of the same software. Because, as #Gordon noted, you cannot do exactly this:
class SomeClass {
premium_file = "premium.php";
if (file_exists($premium_file)) {
require($premium_file);
}
Instead I do this:
premium_file = "premium.php";
if (file_exists($premium_file)) {
require($premium_file);
}
class SomeClass {
...
For functions you want to reference, create class methods in the main class, and call the included file's method, passing the $this pointer as a parameter. So that I can tell at a glance where functions are, I will prefix the name of the included functions as shown below:
class SomeClass {
...
// Premium functions
public function showlist() {
premium_showlist($this);
}
You can include or require before declaring your class like below:
require 'path-to-file';
class myClass{
function show($uid){
}
}
The answer is yes, for example:
Into class construct, pass to the function (that's into the included file) values as params:
$this->wpd = $this->wpdopt = 'something';
include_once('/common/functions_common.php');
$this->wpdb = wpquery($sql='', $mode='', $this->wpd);
Into the included functions_common.php file:
function wpquery($sql, $mode, $wdp)
{
if(!empty($wdp))
{ return true; } else { return false; }
}
Into class methods:
$sql = "UPDATE ..... SET ... WHERE LOWER(user_email) = . ...";
$this->wpdb = wpquery($sql,'update',$this->wpd);
OR
$retval_var = $this->wpdb = wpquery($sql,'update',$this->wpd);
OR even
$this->var = $this->wpdb = wpquery($sql,'update',$this->wpd);
Cheers to all the lovely and cool people
I came across this recently, and came up with a solution, that helped in my case. I wanted many functions in a class, but the class became bloated, so wanted to separate out the class functions into groups for readability. It took a little time to accomplish, but since the functions of the class didn't rely (much) on $this, I removed "$this" from the class functions and created several helper files to include those functions. When $this was necessary, I could nevertheless move the function into a helper file, by passing $this to the function, adding public set/get functions where necessary. It's a hack, but it's sure to help someone
class myClass
{
var x;
function myClass()
{
$this->x = 0;
}
function myFunc1Group1()
{
$x = $this->x;
$x++;
$this->x = $x;
}
function myFunc2Group1(){}
function myFunc1Group2(){}
function myFunc2Group2(){}
}
can be worked around to
class myClass
{
var x;
function myClass()
{
$this->x = 0;
}
function doSomething()
{
// not called on $this but takes $this as a parameter
myFunc1Group1($this);
}
}
and helper function set 1
function myFunc1Group1($THIS_OBJECT)
{
$x = $THIS_OBJECT->getX();
$x++;
$THIS_OBJECT->setX($x);
}
function myFunc2Group1($THIS_OBJECT){}
and helper function set 2, etc.
Probably not the best route in all cases, but helped me out a lot. Basically the class functions were only to construct and delegate, and the calculations were put into helpers.
Is it possible to dynamically extend a class object in PHP? And what would be the most elegant way of doing this?
Some example code for further explanation:
class BasicClass {
private $variable;
public function BasicFunction() {
// do something
$this->variable = 10;
}
}
class ExtendedClass extends BasicClass {
public function ExtendedFunction() {
// do something else with basic class variable
return $this->variable/2;
}
}
$A = new BasicClass();
If(condition for extension){
// A should be of class ExtendedClass
// and the current class variables should be kept
// ... insert the magic code here ...
// afterwards we would be able to use the ExtendedFunction with the original variables of the object
$A->ExtendedFunction();
}
One way of tackling this would be creating a new object of ExtendedClass and copying all the variables from the old object. But can this be done more elegantly?
Yes. It is possible. One way to do it would be using anonymous classes or simply overwriting the class itself(in your case $A) but that implies a little more logic and it's not as clean, so I won't get into it.
NOTE: Support for anonymous classes was added in PHP 7.
Using your example above we can compose the following code(I changed the visibility of the property in order to be able to use it in the extended class. I'd suggest you add a getter rather than changing the visibility).
class BasicClass {
public $variable;
public function BasicFunction() {
// do something
$this->variable = 10;
}
}
class ExtendedClass extends BasicClass {
public function ExtendedFunction() {
// do something else with basic class variable
return $this->variable / 2;
}
}
$A = new BasicClass();
if (TRUE) {
// A should be of class ExtendedClass
$A = new class extends ExtendedClass {
};
$A->ExtendedFunction();
}
Do note that this will overwrite $A. You'll still have all the available methods in it since inheritance is not lost by doing this.
Obviously whichever approach you take won't be the cleanest way you can do this.
My answer stands, but if you were to edit your question and provide more details on what it is you want to actually achieve by doing this perhaps a different approach is more suitable.
You can also achieve some magic using eval and possibly Reflection, but they're so magically magic I refuse to write the answer since it promotes such bad practices.
I've been trying for a long time now to find a correct design using PHP to achieve what I want, but everything I've tried failed and I'm guessing it's probably because I'm not looking from the right angle, so I wish some of you can enlighten me and give me some good advice!
The design might seem a little weird at first, but I assure you it's not because I like to make things complicated. For the sake of simplicity I'm only giving the minimal structure of my problem and not the actual code. It starts with these:
<?php
// ------------------------------------------------------------------------
class Mother_A
{
const _override_1 = 'default';
protected static $_override_2 = array();
public static function method_a()
{
$c = get_called_class();
// Uses $c::_override_1 and $c::$_override_2
}
}
// ------------------------------------------------------------------------
class Mother_B extends Mother_A
{
public function method_b()
{
// Uses self::method_a()
}
}
Class Mother_A defines a static method that uses constants and statics to be overridden by children. This allows to define a generic method (equivalent of a "template" method) in the derived class Mother_B. Neither Mother_A or Mother_B are intended to be instanciated, but Mother_B should not be abstract. This exploits Late Static Binding, which I find very useful btw.
Now comes my problem. I want to define two classes, in n distinct 'situations' (situation 1, situation 2, etc):
<?php
// ------------------------------------------------------------------------
class Child_A_Situation_k extends Mother_A
{
// Uses method_a
}
// ------------------------------------------------------------------------
class Child_B_Situation_k extends Mother_B
{
// Uses method_a and method_b
}
Of course I'm not actually giving these stupid names; both classes have different names in each situation, but both follow the same derivation pattern from Mother_A and Mother_B. However, in each individual case ('situation'), both classes need the exact same constants/static override, and I don't know how to do that without duplicating the override manually in both classes.
I tried many things, but the closest I got was to implement an interface Interface_Situation_k that defined constants and statics for the situation k, and make both children implement this interface. Of course, you can't define statics in an interface, so it failed, but you get the idea. I would have traded the interface for a class, but then there's no multiple inheritance in PHP, so it's not valid either. :/ I'm really stuck, and I can't wait to read a possible solution! Thanks in advance!
this is the best i can do, i don't think there is a way to do it with less code.
Look at the comments inside the code for more info.
Fully working code:
<?php
class Mother_A
{
// you're using '_override_1' as a variable, so its obviously not a constant
// also i made it public for the setSituation function,
// you could keep it protected and use reflections to set it
// but i dont really see a reason for that.
// if you want that, look up how to set private/protected variables
public static $_override_1 = 'default';
public static $_override_2 = array();
public static function method_a()
{
$c = get_called_class();
var_dump($c::$_override_1);
var_dump($c::$_override_2);
// Uses $c::_override_1 and $c::$_override_2
}
public static function setSituation($className)
{
$c = get_called_class();
// iterate through the static properties of $className and $c
// and when the you find properties with the same name, set them
$rBase = new ReflectionClass($c);
$rSituation = new ReflectionClass($className);
$staBase = $rBase->getStaticProperties();
$staSituation = $rSituation->getStaticProperties();
foreach($staSituation as $name => $value)
{
if(isset($staBase[$name])) $c::$$name = $value;
}
}
}
// ------------------------------------------------------------------------
class Mother_B extends Mother_A
{
public function method_b()
{
self::method_a();
}
}
class Situation_k
{
public static $_override_1 = 'k';
public static $_override_2 = array('k','k');
}
class Child_A_Situation_k extends Mother_A { }
Child_A_Situation_k::setSituation('Situation_k');
// This is not as short as writing 'extends Mother_A, Situation_k'
// but i think you wont get it shorter
class Child_B_Situation_k extends Mother_B { }
Child_B_Situation_k::setSituation('Situation_k');
echo '<pre>';
Child_A_Situation_k::method_a();
echo "\n";
Child_B_Situation_k::method_a();
echo "\n";
Child_B_Situation_k::method_b();
echo "\n";
echo '</pre>';
?>
I`ve been wondering how to implement methods in a class.
Could someone explain me what means if one does OOP in procedural style?
Here is an example:
class Fld extends Model {
private $file;
private $properties = array();
public function init($file) {
$this->file = $file;
$this->parseFile();
}
private function parseFile() {
// parses the file
foreach($this->file as $line) {
//..................
}
$this->properties = $result;
}
}
I mean is it a good thing to have methods like these that do operations for the class properties like that. Or should I pass the class property as method parameter...
I mean this would cause error if the file property wouldnt be declared.
If the file is mandatory for you object, it should be a parameter in your constructor.
class Fld extends Model {
private $file;
private $properties = array();
function __construct($file) {
$this->file = $file;
}
public function parse() {
foreach($this->file as $line) {
/* ... */
$this->properties = $result;
}
}
}
When there is a method in your class which does not use any of the class properties, you should think about making that method static or even create a separate class for this method.
I think people describe code as "OOP in procedural style" when the methods inside a class tend to be very long and complex.
Martin Fowler's book 'Refactoring', describes a long method as a 'code smell' that hints that parts of its code could be broken down into smaller methods or separated out into other classes.
see: http://books.google.co.uk/books?id=1MsETFPD3I0C&lpg=PP1&dq=refactoring&pg=PA76#v=onepage&q&f=false
I think your code is perfectly fine. Just bare in mind how disposable the objects of the class are. Generally a 'parsing service' like this should be created, used and thrown away. Then you won't have to worry about old properties causing confusion if it is re-used.
As eteubert suggests, passing the tooling in the constructor helps to let the clients know that the object is being created for a very particular purpose.
I want to make a PHP class, lets say Myclass.php. Now inside that class I want to define just the class itself and some instance variables. But all the methods must come from a Myclass_methods.php file. Can I just include that file into the class body?
I have good reasons why I want to seperate this. In short, I'll have a backend in which I can change the business logic of a class, while all other things must remain untouched. The system maintains all the ORM and other stuff for me.
But if this is a bad idea, it might be better to re-generate the whole class file after editing the business logic (so, the user-defined methods in this case).
Performance question: If during one request Myclass.php is included just once, actually that Myclass_methods.php should also be included just once. Might be wrong. Experts?
No. You cannot include files in the class body.
In a file defining a class, you may only include files in a method body or outside the class body.
From your description I take you want this:
<?php // MyClass.php
class MyClass
{
protected $_prop;
include 'myclass-methods.php';
}
<?php // myclass-methods.php
public function myMethod()
{
$this->$_prop = 1;
}
Running this code will result in
Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION
What is possible though is this
<?php // MyClass.php
class MyClass
{
protected $_prop;
public function __construct() // or any other method
{
include 'some-functions.php';
foo($b); // echoes 'a';
}
}
<?php // some-functions.php
$b = 'a';
function foo($str)
{
echo $str;
}
Doing it this way, will import the contents of the include file into the method scope, not the class scope. You may include functions and variables in the include file, but not methods. You could but should not put entire scripts into it as well and change what the method does, e.g.
<?php // MyClass.php
// ...
public function __construct($someCondition)
{
// No No Code here
include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php';
}
// ...
<?php // whatever.php
echo 'whatever';
<?php // default.php
echo 'foo';
However, patching the class this way to exhibit different behavior is not how you should do it in OOP. It's just plain wrong and should make your eyes bleed.
Since you want to dynamically change behavior, extending the class is also not a good option (see below why). What you really will want to do is write an interface and make your class use objects implementing this interface, thus making sure the appropriate methods are available. This is called a Strategy Pattern and works like this:
<?php // Meowing.php
interface Meowing
{
public function meow();
}
Now you got the contract that all Meowing Behaviors must obey, namely having a meow method. Next define a Meowing Behavior:
<?php // RegularMeow.php
class RegularMeow implements Meowing
{
public function meow()
{
return 'meow';
}
}
Now to use it, use:
<?php // Cat.php
class Cat
{
protected $_meowing;
public function setMeowing(Meowing $meowing)
{
$this->_meowing = $meowing;
}
public function meow()
{
$this->_meowing->meow()
}
}
By adding the Meowing TypeHint to setMeowing, you make sure that the passed param implements the Meowing interface. Let's define another Meowing Behavior:
<?php // LolkatMeow.php
class LolkatMeow implements Meowing
{
public function meow()
{
return 'lolz xD';
}
}
Now, you can easily interchange behaviors like this:
<?php
require_once 'Meowing.php';
require_once 'RegularMeow.php';
require_once 'LolkatMeow.php';
require_once 'Cat.php';
$cat = new Cat;
$cat->setMeowing(new RegularMeow);
echo $cat->meow; // outputs 'meow';
// now to change the behavior
$cat->setMeowing(new LolkatMeow);
echo $cat->meow; // outputs 'lolz xD';
While you also could have solved the above with inheritance by defining an abstract BaseCat and meow method and then deriving concrete RegularCat and Lolkat classes from that, you have to consider what you want to achieve. If your cats will never change the way they meow, go ahead and use inheritance, but if your RegularCat and Lolkat is supposed to be able to do arbitrary meows, then use the Strategy pattern.
For more design patterns in PHP, check these resources:
http://www.php.net/manual/en/language.oop5.patterns.php
http://www.ibm.com/developerworks/library/os-php-designptrns/
http://www.fluffycat.com/PHP-Design-Patterns/
http://sourcemaking.com/design_patterns
Might it not be an idea to create the core class with the relevant base functionality and then extend this with the required methods - it seems like a more logical approach.
I'll start by saying I'm not too clear why this problem is not best solved using a base class containing the methods, subclasses containing the data, and dynamic class loading. I'll assume you have a good reason.
Once your provider supports PHP 5.4 you can do what you want using traits.
Code File:
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');
class Pet {
use PetSounds;
}
$myPet = new Pet();
$myPet->speak();
File cat.php
trait PetSounds {
function speak() { echo 'meow'; }
}
File dog.php
trait PetSounds {
function speak() { echo 'woof'; }
}
You could make this even cleaner by naming both include files the same, putting them in different subdirectories, and using set_include_path() or defining an __autoload() function to select between them. Like I said though, this same problem could be solved better using inheritance. If you have a multiple-inheritance type problem though, if for instance you have four kinds of pets with five kinds of colors with three hair types and you need a different combination of methods for each of the 60 different classes, this is the right solution.
5.4 is currently just a Release Candidate (as of 2/24/2012) and even once released most hosts will not support it for many months - mine took 18 months after 5.3 was released before they would support it. Until then you must write entirely separate and complete class files. You can however format your classes with an eventual change to traits in mind.
Right now you can partially get what you want using magic methods and have an easy upgrade to traits when they are available.
Code File:
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');
class Pet {
public function __call($name, array $arguments)
{
array_unshift($arguments, $this);
return call_user_func_array("TraitFunc_$name", $arguments);
}
}
$myPet = new Pet();
$myPet->speak();
File cat.php
function TraitFunc_speak(Pet $that) { echo 'meow'; }
File dog.php
function TraitFunc_speak(Pet $that) { echo 'woof'; }
You are limited however in that your functions can not access private and protected class properties and methods and you can not use this method to provide magic methods such as __get(). Traits will solve both of those limitations.
What about using traits for this? Would that be an acceptable option? This is something I am currently experimenting with and it seems to work quite while.
A simplified version of what I am doing is basically like this. I have an application with shared core files and multiple projects. Within those projects i have modules. I want to have functions that are available for the entire project on a core level but only for that specific project.
My project controller
if(is_file(PROJECT_PATH.'/project_extensions.trait.php')){
// additional functions for this specific project
require_once(PROJECT_PATH.'/project_extensions.trait.php');
}else{
// no additional functions
trait Extensions{};
}
Class Project{
USE Extensions;
// default functions shared between all projects
function shared_stuff(){
}
}
Extensions file
trait Extensions{
// project-specific extensions
function this_project_only(){
echo 'Project Only';
}
}
Module file in the project
class MyModule extends Modules{ // modules extends projects in a different class not relevant here
function do_something(){
echo $this->project_only();
}
}
Since PHP5.4 release you can create dynamic objects like this: https://github.com/ptrofimov/jslikeobject
But this is scarcely the best practice.
Reviving an old question but this is a fairly simple solution. Do you need the common function calls to be exclusive to your class? If not, simply include your common function file(s) within the same scope as your class. You will need to create methods in your class but they will only need to call the common function. Here's a simple SOAP server example:
<?php
include 'post_function.php';
$server = new SoapServer( null, array('uri' => "http://localhost/") );
$server->setClass( 'postsoapclass' );
$server->handle();
class postsoapclass
{
public function animalNoise( $animal )
{
return get_animal_noise($animal);
}
}
?>
post_function.php
<?php
function get_animal_noise($animal)
{
if(strtolower(trim($animal)) == 'pig')
{
return 'Oink';
}
else
{
return 'This animal is mute';
}
}
?>
I have had to do what you are describing in cases where I maintain a free version and a premium version of the same software. Because, as #Gordon noted, you cannot do exactly this:
class SomeClass {
premium_file = "premium.php";
if (file_exists($premium_file)) {
require($premium_file);
}
Instead I do this:
premium_file = "premium.php";
if (file_exists($premium_file)) {
require($premium_file);
}
class SomeClass {
...
For functions you want to reference, create class methods in the main class, and call the included file's method, passing the $this pointer as a parameter. So that I can tell at a glance where functions are, I will prefix the name of the included functions as shown below:
class SomeClass {
...
// Premium functions
public function showlist() {
premium_showlist($this);
}
You can include or require before declaring your class like below:
require 'path-to-file';
class myClass{
function show($uid){
}
}
The answer is yes, for example:
Into class construct, pass to the function (that's into the included file) values as params:
$this->wpd = $this->wpdopt = 'something';
include_once('/common/functions_common.php');
$this->wpdb = wpquery($sql='', $mode='', $this->wpd);
Into the included functions_common.php file:
function wpquery($sql, $mode, $wdp)
{
if(!empty($wdp))
{ return true; } else { return false; }
}
Into class methods:
$sql = "UPDATE ..... SET ... WHERE LOWER(user_email) = . ...";
$this->wpdb = wpquery($sql,'update',$this->wpd);
OR
$retval_var = $this->wpdb = wpquery($sql,'update',$this->wpd);
OR even
$this->var = $this->wpdb = wpquery($sql,'update',$this->wpd);
Cheers to all the lovely and cool people
I came across this recently, and came up with a solution, that helped in my case. I wanted many functions in a class, but the class became bloated, so wanted to separate out the class functions into groups for readability. It took a little time to accomplish, but since the functions of the class didn't rely (much) on $this, I removed "$this" from the class functions and created several helper files to include those functions. When $this was necessary, I could nevertheless move the function into a helper file, by passing $this to the function, adding public set/get functions where necessary. It's a hack, but it's sure to help someone
class myClass
{
var x;
function myClass()
{
$this->x = 0;
}
function myFunc1Group1()
{
$x = $this->x;
$x++;
$this->x = $x;
}
function myFunc2Group1(){}
function myFunc1Group2(){}
function myFunc2Group2(){}
}
can be worked around to
class myClass
{
var x;
function myClass()
{
$this->x = 0;
}
function doSomething()
{
// not called on $this but takes $this as a parameter
myFunc1Group1($this);
}
}
and helper function set 1
function myFunc1Group1($THIS_OBJECT)
{
$x = $THIS_OBJECT->getX();
$x++;
$THIS_OBJECT->setX($x);
}
function myFunc2Group1($THIS_OBJECT){}
and helper function set 2, etc.
Probably not the best route in all cases, but helped me out a lot. Basically the class functions were only to construct and delegate, and the calculations were put into helpers.