PHP Overload class by other with the same name and namespace - php

I have a directory tree where in different sub-directories I have a lot of classes with the same name. There is a strong intention to not edit these classes.
I'm looking for a way to load one class and after using it and destroying its instance load another with exactly the same name. Then use it, destroy its instance and repeat that process.
I thought some possible solutions:
Loading class with the same name that replaces previously loaded class (Overloads it)
Unloading a class before I load class with the same name but from different path
Creating a new class (dynamically created class body) under different name or by adding to it namespace. Creation process firstly reads source class body, its methods, properties and "copies" that to new class. Similar to clone on instances but done on class body level.
Read the first class, instantiate it, use its methods, destroy its instance. Then remove all methods inside first class and dynamically create inside it all methods that are read from the second class having the same name.
Read file content of a class and create temporary file with the class content you read but change class name or put unique namespace on top of it and finally load temporary file. (Least appealing approach to me)
For the 3rd I thought this could be useful: Componere or Runkit or Classkit but don't have any experience with them.
Do you have any other ideas or perhaps some solutions?
Did you use componere or Runkit / Classkit and can say they suit the job? maybe there are other options?
Perhaps there is a OOP design pattern that covers this issue but I'm not familiar with it.
Example code:
<?php
#------------------------------------
//path Foo/Bar.php
/* class is without a namespace or have the same
as Baz/Bar.php */
class Bar
{
public function getName() : string
{
return 'Foo/Bar';
}
}
#------------------------------------
//path Baz/Bar.php
/* class is without a namespace or have the same
as Foo/Bar.php */
class Bar
{
public function getName() : string
{
return 'Baz/Bar';
}
}
#------------------------------------
//path ./Execute.php
$paths = [
'Foo/Bar.php',
'Baz/Bar.php'
];
$results = [];
foreach ($paths as $path) {
//how to create instance of class Bar in Foo/Bar.php and then in Baz/Bar.php
//without PHP Fatal error: Cannot declare class...
$classDynamic = ...
$results[] = $classDynamic->getName();
unset($classDynamic);
}
var_export($results)
/**
* prints
* array('Foo/Bar', 'Baz/Bar')
*/

I do not think there is a way to unset a class once it has been defined and as they share the same namespace they will error out.
but you could get the effect you wanted as follows
class Bar
{
$myname = "";
function __construct($setname="")
{
$this->myname = $setname;
}
function getName()
{
return $myname;
}
}
$paths = array('Foo/Bar','Baz/Bar');
$results = array();
foreach($paths as $p)
{
$bit = new Bar($p);
$results[] = $bit->getName();
}
var_export($results);

Related

add more methods to class using include_once [duplicate]

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.

Static variable assignment in descendent bubbles up to parent?

I've run into a problem and I'm not sure if this is just normal behaviour or if I wrote something wrong. I have a method in my base class that applies a global filter to a given class by way of creating a proxy for all new instances of that particular class. The way I planned to go about it is as follows:
Attach static $global_filter (the proxy) to the class I want to be filtered, which extends the base class object
Via my loading mechanism, return the proxy instead of the actual class upon new instantiations (which will mask method calls and apply filters accordingly)
However, I am getting stuck in step 1 and it seems that when I try to assign static $global_filter to the descendent class I want filtered, my base class object also gets the same assignment, which breaks everything else that extends from it.
Please see below for relevant code:
class object {
public static $global_filter;
public function _filterGlobal($class, $method, $callback) {
if ( !is_object($class::$global_filter) ) {
$class::$global_filter = new filterable(null);
# Replace the object being called with the new proxy.
}
var_dump($class);
var_dump($class::$global_filter); // `filterable`
var_dump(\core\blueprint\object::$global_filter); // Returns same as line above
die();
return $class::$global_filter->_add($method, $callback);
}
}
Both $class::$global_filter and \core\blueprint\object::$global_filter (the base class) are returning same instance. Whereas I expected object::$global_filter to be null.
I'm not using late static binding in order to preserve consistency (both single-object filters and global filters are called much in the same way non-statically).
This question seems relevant
Any help will be much appreciated :)
Edit, full example
This would be a concrete class, which extends model which extends object
<?php
use core\blueprint\model;
class modelMock extends model {
protected $schema = array();
public function method($test) {
return $test;
}
}
This would be another object (e.g a controller), which extends object aswell. It applies a filter to all new instances of model
<?php
use core\blueprint\object;
class objectMock extends object {
public function applyFilters() {
$this->_filterGlobal('core\blueprint\model', 'method', function($self, $chain) {
$chain->params[0] = 'new param'; // adjust the paramters
return $chain->next();
});
}
}
when I try to assign static $global_filter to the descendent class I want filtered, my base class object also gets the same assignment
Yes, indeed this happens. A static property in essence is a global variable, constrained within the class's namespace. Running into problems with global variables is often an indication you're not using the best solution.
To solve your problem, you could make the filter a (non-static) property:
$class->$filter = new Whatever();
But as always, there's more roads that lead to Rome, and I would advise you to look for alterative ways to do it.
I don't know if this is a help for you:
class a {
public static $type;
public static function setType($class, $newType) {
$class::$type = $newType;
var_dump($class::$type);
}
}
class b {
public static $type = 'myType';
}
var_dump(b::$type);
a::setType('b', 'yourType');
var_dump(a::$type);
May be you have not defined the static property to the concrete class.
Thanks everyone for you help, I spent some time on it this morning and managed to solve my problem. It's a bit of a workaround but here's how it goes:
public function _filterGlobal($class, $method, $callback) {
if ( !is_object($class::$global_filter[$class]) ) {
$class::$global_filter[$class] = new filterable(null);
# Replace the object being called with the new proxy.
}
return $class::$global_filter[$class]->_add($method, $callback);
}
So basically in order to get unique static variables working in child classes without having to explicitly define them, you can use an array that stores the child's class name as a key and then access these variables via a getter.

Nested Dynamic PHP Class

I may just need a terminology update, but I have been playing in Magento and Joomla, and they do references like
$mage = new Mage;
$mage->block('blockname');
where class Mage through some process I am failing to figure out is calling:
class blockname extends something{
}
Don't quote me on that code, however I am looking to do something like that where I have a file that I can do $myscript->block('blockname'); and it will load and call the file with class blockname.
class Mage {
private $block;
public function block($blockname) {
if (!class_exists($blockname, true)) {
throw new InvalidArgumentException("Not a valid class name: $blockname");
}
$this->block = new $blockname;
}
}
The loading of the class definition (if not already done) is typically accomplished through autoloading (see here).

Create a PHP Class -> Create an object of it in another class

I have created a PHP class called formChecker.php. It validates a form. As a Java programmer, I would like to stick with the idea of creating an instance of this class in another class and run it from there. It doesn't seem to be working for me.The following is a demonstration:
class formChecker{
..... validation functions go here
}
class runFormChecker{
.... create instance of formchecker here and use it's methods etc.
}
Can this be done? What I'm thinking of is developing a number of classes that can be run seperately.
GF
I'd rather pass the instance of formChecker (or something that implements a certain interface) to the instance of runFormChecker. see http://en.wikipedia.org/wiki/Dependency_injection
Could be as simple as
interface FormChecker {
public function foo($x);
}
class MyFormChecker implements FormChecker
public function foo($x) {
return true;
}
}
class RunFormChecker {
protected $formChecker=null;
public function __construct(FormChecker $fc) {
$this->formChecker = $fc;
}
// ....
}
$rfc = new RunFormChecker(new MyFormChecker);
Just include the formChecker class file just before the class you want to use it in eg:
include "formChecker.php"
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
If however, you have both classes in one file (which is bad), then no need to include the file, you can create the instance of that straight away eg:
class formChecker{
// ............
}
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
More Information Here....
Thanks :)
Yes, and this is not strange. You would usually create the instance of formChecker within an instance of runFormChecker though, and not at the class level.

Can I include code into a PHP class?

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.

Categories