I have master class for the whole project. I need to call master class functions to different pages and methods as described below:
Master.php
class master{
function login_parser(){
}
}
Index.php
include('master.php')
function test(){
$obj = new master();
}
function test2(){
obj = new master();
}
I need to call object for every method. Is there any way to call an object in single time?
You could give that object as a parameter to the function, so it's also clear that there is a dependency to this object which can also be typehinted (which gets lost if just using it via global)
$obj = new master();
function test(master $obj) {
...
}
and then call:
test($obj);
There are a lot of ways to achieve this
Tobias Zander gave the option of parameters (dependency injection)
pros: know what the function needs
cons: could end up with giving a lot of parameters to a function
$obj = new master();
function test(master $obj) {
...
}
The second way could be using globals
pros: no paramter chain
cons: don't know what dependencies the function has
$obj = new master();
function test(){
global $obj; //Now carry on
}
The third way, singleton
pros: object orientated way
cons: dont know the dependencies
In this your master class needs a static function that returns itself
class Master
{
protected static $master ;
public static function load()
{
if(!self::$master instanceof Master) {
self::$master = new Master();
}
return self::$master;
}
}
Now i can use the master every where in my script using the load function, and it will only be initiated once
function test()
{
$master = Master::load();
}
I personaly use method 1, but than for a class
class Test
{
protected $master;
public function __construct(Master $master)
{
$this->master = $master;
}
public function whoo()
{
// now I can use $this->master as the master class
}
}
Yes, Instead of creating object everytime. Create on outside the functions on global scope.
include('master.php')
$obj = new master();
function test(){
global $obj; //Now carry on
}
function test2(){
global $obj;
}
Related
I have a class that using an external package to do something
class MyClass
{
public function doSomething($data){
$external = new External();
$external->doSomething($data);
}
}
This class is called from another class, for example:
class MasterClass
{
public function go(){
$data = 'whatever';
$data2 = 'whatever2';
$myClass = new MyClass();
$myClass->doSomething($data);
$myClass->doSomething($data2);
....
}
}
So in my MasterClass I am calling the doSomething function multiple times. WHich creates a new External class multiple times - which is not really necessary.
How can I get around this issue and only create the external class once?
class MyClass
{
protected $external;
public function doSomething($data){
if(!$this->external){
$this->external = new External();
}
$this->external->doSomething($data);
}
}
But read about dependency injection in php.
Move the new External() call into the constructor and store it as a property, then reference that property in the doSomething() method instead of constructing a new instance every time.
Alternatively, if you don't want to always construct a new External whenever you construct a MyClass, you could move the construction into a Lazy Load static method called something like getExternal() in External class.
The first time that method is called it would need to store a new instance of External as a property, but on subsequent calls (when the property is already set) return the same instance. This type of pattern is called Singleton Pattern in Object-Oriented Design Patterns.
You could refer to this link to know more about singleton pattern and how it is implemented.
Pass External class in constructor.
class MyClass
{
private $external;
public function __construct(External $external)
{
$this->external = $external;
}
public function doSomething($data)
{
$this->external->doSomething($data);
}
class MasterClass
{
public function go() {
$data = 'whatever';
$data2 = 'whatever2';
$external = new External();
$myClass = new MyClass($external);
$myClass->doSomething($data);
$myClass->doSomething($data2);
....
}
}
I am new to php and trying to call a function in another class.
How do I call function1 and function2 in class xyz???
class abc {
private $lmn = "lmn";
private $say1;
private static $static;
private function __construct(){
$say1 = print $this->lmn;
}
public static function1(){
$static = "YEAAHHHH";
}
public function function2(){
return $this->say1;
}
file 2:
require 'abc.php';
class xyz {
/**
* $e = new xyz();
*
*/
$e = xyz:: function1();// error
$d = xyz:: function 2(); //error
}
Also under what circumstance I should use
$obj = new class();
$obj->functionname();
and
$obj = class::functionname();
You have 2 different types of methods here, static and non-static.
To call the static (function1())
You don't need to instantiate the class, as it's static.
class zyx {
public function foo() {
return abc::function1();
}
}
To call the non-static (function2())
You need to instantiate the class, as it's not static.
class zyx {
public function foo() {
$abc = new abc();
return $abc->function2();
}
}
You would call function1 like:
abc::function1();
It is a method in abc not xyz.
function2() you would only call if you had an instance of abc because it is an instance method and not a static method. I.e.
$abc = new abc();
$abc->function2();
Static functions are intended to be called on classes, instance methods (i.e. function2() are intended to be called on instances of classes. I would recommend reading http://php.net/manual/en/oop5.intro.php.
Static functions can be called without instantiating your class...
$myClass::function1();
Non-static functions need to be instantiated first:
$myClass = new abc();
$myClass->function2();
So in your example:
require 'abc.php';
class xyz {
public function CallFunc1()
{
abc::function1();
}
public function CallFunc2()
{
$myClass = new abc();
$myClass->function2();
}
}
require 'abc.php';
class xyz {
public function static(){
return abc:: function1();// this is a static function
}
public function nonstatic(){
$e = new abc();
return $e->function2();
}
}
First of all, you can't have a space between function and 2():
$d = xyz::function2(); //correct
$d = xyz::function 2(); //very incorrect
I was going to have a second of all, but #hd beat me to it.
I think you have messed up with the code. I can share something with something that I found very helpful as an answer for your second question. Spend a bit time reading this. This is very basic, simple and well guided.
http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
If I have a class like:
class MyClass
{
public function foo()
{
echo "foo";
}
}
And then outside of the class instantiate it and try to create an anonymous function in it:
$mine = new MyClass();
$mine->bar = function() {
echo "bar";
}
And then try to call it like $mine->bar(), I get:
Fatal error: Call to undefined method MyClass::bar() in ...
How can I create an anonymous function / closure on a class instance?
Aside: Before you tell me I should rethink my logic or use interfaces and OOP properly, in my case, it's a convenience method that applies to this specific instance of a bastardized class in an attempt to clean-up a legacy procedural application. And yes, I'm using PHP 5.3+
See my blog article here: http://blog.flowl.info/2013/php-container-class-anonymous-function-lambda-support/
You need to add a magic __call function:
public function __call($func, $args) {
return call_user_func($this->$func, $args);
}
The problem is that within this construct you can call private methods from public scope.
I suggest not to simply add new variables to a class that are not defined. You can avoid this using magic __set functions and catch all undefined variables in a container (= array, like in my blog post) and change the call_user_func behaviour to call only inside the array:
// inside class:
public $members = array();
public function __call($func, $args) {
// note the difference of calling only inside members:
return call_user_func($this->members[$func], $args);
}
__call
This will work.
class Foo {
public $bar;
public function __construct()
{
$this->bar = function()
{
echo 'closure called';
};
$this->bar();
}
public function __call($method, $args) {
return call_user_func($this->$method, $args);
}
}
new Foo();
The function IS being created.
PHP has a problem with calling it.
Dirty, but works:
$f = $mine->bar;
$f();
We have the following chaining:
$obj = new obj();
$obj->setname($params1)->setcolor($params2);
Is there a way to do the same chaining on one line, without creating a dummy function?
P.S: I want to skip the part where the constructor itself is on a new line. I want to construct the object and start the chaining on the same line. Something like this:
$obj = new obj()->setname($params1)->setcolor($params2);
Since PHP 5.4, class member access on instantiation has been added so you can do it like this:
$obj = (new obj())->setname($params1)->setcolor($params2);
In previous versions, like you I hate that you have to instantiate the object on one line and then start using it on another, so I have a global function _i() which looks like this:
function _i($i) { return $i; }
I use it like this:
_i(new Obj)->doThis($param)->doThat($param2);
Some people will find it ugly but PHP lacks language expression power, so it works for me :)
I use static functions of class for it.
class a{
static public function gets($args){
return new self($args);
}
public function do_other(){
}
}
a::gets()->do_other();
Usually there are more then I static method to different usages
Should be possible if you allways return the object itself in the function.
function setname($param) {
// set the name etc..
return $this;
}
You can also use PHP type hinting to make sure only the correct object is used as an argument
function instance(sdtClass $instance) { return $instance }
or as the static method using the class name
class CustomClass{
static public function gets(CustomClass $obj){
return $obj;
}
}
You can also use this technique from Singleton pattern (without using singleton pattern):
<?php
class test
{
public function __construct() {
}
public static function getInstance() {
return new test();
}
public function chain() {
echo 'ok';
}
}
// outputs 'ok'
$test = test::getInstance()->chain();
Sure is. Simplt return this at the end of each function, to return the object so your next chained function can use it.
<?php
class A
{
public __constructor()
{ .... }
public function B($params)
{
//Processing
return this;
}
public function C($params)
{
//Processing
return this;
}
public function D($params)
{
//Processing
}
}
$O = new A();
$O->B($params)->C($params)->D($params); //Will work because B and C return this
$O->B($params)->D($params)->C($params); //WILL NOT work because D doesn't return this
?>
Hi i have a little collection of classes some of which should be globally accessible.
I found something similar in Zend_Registry, but reading its code i cant understand how a call to a static function could return an initialized instance of a class...
i need to do something like:
<?php
//index.php
$obj = new myUsefulObject();
$obj->loadCfg("myFile.xml");
$req = new HTTPRequest();
$req->filter("blablabla");
myappp::registerClass("object",$obj);
myappp::registerClass("request",$req);
$c = new Controller();
$c->execute();
?>
Here i have filtered the Request object and i want the controller to be able to reach that already filtered request.
<?php
class Controller
{
function __construct()
{
$this->request = Application::getResource("request");//This must be the filtered var =(
}
}
?>
I don't know how to implement that Application::getResource(), the only thing i know is that it must be a static method because it can't be related to a specific instance.
Aside from static methods, PHP also has static properties: properties that are local to the class. This can be used to implement singletons, or indeed a Registry:
class Registry {
private static $_registry;
public static function registerResource($key, $object)
{
self::$_registry[$key] = $object;
}
public static function getResource($key) {
if(!isset(self::$_registry[$key]))
throw InvalidArgumentException("Key $key is not available in the registry");
return self::$_registry[$key];
}
}
1: You can acess global variables with the global keyword:
$myVar = new SomethingProvider();
class MyClass {
public function __construct() {
global $myVar;
$myVar->doSomething();
}
}
2: You can do the same using the $GLOBALS super-global:
$myVar = new SomethingProvider();
class MyClass {
public function __construct() {
$GLOBALS['myVar']->doSomething();
}
}
3: You can define a singleton class (the wikipedia has a nice example, too).
4: You could add globals as public static members (or private static members with public getters/setters) to a class:
class Constants {
const NUM_RETIES = 3;
}
if ($tries > Constants::NUM_RETRIES) {
# User failed password check too often.
}
class Globals {
public static $currentUser;
}
Globals::$currentUser = new User($userId);
I wouldn't recommend the first two methods, overwriting the values of these global variables unintentionally is too easy.
Seems to me like you might need some form of Singleton design pattern;
Check this out!
Hope it helps!