I'm creating a class that uses google.
I want to return the value as an object from another class.
Example:
$x = new SocialServices($key, $keySecret, $apiKey);
Here I call the Google() method which requires a google.php file and creates the new object
$x->Google();
Here I want return Google class as $this.
public function Google() {
require 'PHP/google.php';
new Google($this->key, $this->secret, $this->apiKey, "#Google");
}
When i call
$x->YouTube();
It will be works.
I'm not sure I fully understood what you're asking, but I know for sure that you are missing a return in your method.
That means that the working method that returns a Google object would be
public function Google() {
require 'PHP/google.php';
return new Google($this->key, $this->secret, $this->apiKey, "#Google");
}
What I don't understand is what you mean by "Here I want return Google class as $this". I you want the method to return the same object to be able to concatenate, you can assign the Google object to an internal variable declared in the constructor and then just return $this right after the assignment.
By the way I would suggest you to avoid using the require, it's better if you use composer's autoloading.
Related
In my current application I have a number of objects that are required repeatedly
To save overhead of instantiating the same object over and over again, I keep an array of 'known' objects.
I can check the input data against the array, and - if already set - use the existing object, else go ahead to instantiate the new object and add the pointer reference to the relevant known objects array.
In most use cases, I can check prior to instantiating the class:
if(array_key_exists($identifier,$known_ClassObjects)){
$object = $known_ClassObjects[$identifier];
} else {
$object = new Class($params);
}
However, in some cases I can only identify that the object I am instantiating already exists once already inside it.
In that case I would like to be able to do one of 2 things:
return the OTHER (pre-existing) object instead of this one, e.g.
class Test{
public function __construct($params){
//apply processing to $params, resulting in $identifier
if(array_key_exists($identifier, $known_ClassObjects)){ //$known_ClassObjects is global
return $known_ClassObjects[$identifier];
} else {
//continue __construct() logic
return $this;
}
}
}
However, PHP ALWAYS returns the current object, even with code return $other_object;
'Internally Clone' the current object from the found one [of the same class, obv] so that when it returns, it has the correct relevant properties populated.
NOTE: including any parent/child class properties
-> I want to make this object EXACTLY the same as the found one.
So, if there was a PHP function clone_from(), it would work something like:
if(array_key_exists($identifier,$known_ClassObjects)){
$this->clone_from ($known_ClassObjects[$identifier]);
} else {
//continue with __construct()
}
return $this;
Given that 1. doesn't work and 2. doesn't seem to exist, I have only been able to do this in very 'hacky' ways: iterating through all properties of source object and setting all properties of current object.
However, this has obvious issues esp. with extended parent/child classes etc. which then requires things like reflection classes.
This seems like there SHOULD be a really simple solution, but I have been unable to find one
What you actually could do is using either a Singleton Pattern or a Factory pattern - in both cases, the creation of objects is controlled by some piece of code and you can decide, which object to return. Singleton already is a special form of a Factory pattern.
Consider this code
class Singleton {
protected static $instance;
protected function __construct() {
}
public static function instance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
The constructor is protected which will prevent a object construction from "outside" via new. However, there is also a static function instance with which somebody can request an object instance from the factory method.
$obj = Singleton::instance();
So, the (internal) object is created only once, and then delivered afterwards until the script ends.
However, PHP ALWAYS returns the current object, even with code return $other_object;
Constructor is not a regular function. You do not return from it. If you are in __construct() you are already constructing the new object. Before proceed, I strongly recommend you read at least: https://www.php.net/manual/en/language.oop5.decon.php
You most likely need a helper method or factory that would deal with that instead. Putting the logic you tried to place into your constructor is wrong.
Also you missed to clarify what the $identifier really is. But if that's object's property, then you can expose it (i.e. via getter) and have it read for your comparison/whatever by other code.
Inside the definition of a class' method I include an external file. I would like this external file unable to access $this, but only the "public" instance, i.e. only the public methods and properties.
So far I have tried to use anonymous functions, call_user_func with a method returning $this.
I have seen I can unset $this in my anonymous function without altering the rest of the execution, but I haven't found a way to get the instance as I want it. I think I could try to unset all non-public properties and methods in the anonymous function but I wonder if there is not a simpler way.
Class Foo{
private $test = 23;
public function getFoo(){
return $this;
}
public function inclFile($file){
$foo = call_user_func([$this, 'getFoo']);
$r = function()use($foo){
unset($this);
var_dump($foo->test); // i am getting it!
require($file);
};
$r();
// Here $this is still set
}
}
I would turn the design around a bit, and create this function (and place it anywhere):
function access_object_in_file($file_to_require, $object) {
require $file_to_require;
}
This will limit the scope of the file to only have access to $object. Since PHP is PHP, your file will be allowed to create reflection classes, parse back trace etc but the variable scope is limited to $object.
If you do not want any type of objects passed to the function, I would add an interface and type hint for it, such as this:
// let's pretend we're in a view layer
function render($view_file, Properties $object) {
require $file_to_require;
}
Is there a way to get the actual calling object from a method?
For example, I have a scenario where I do something like this:
$user = new User;
$user->setName('name');
$user->save($user);
Instead of passing the $user to the save method, it would be nice to just have it get the calling object information.
I know I can do get_called_class() but that doesn't return the actual object's data. I was also looking at PHP's Reflection classes but didn't see anything exactly right.
Any ideas?
Thanks!
Within your object (and thus from within the save function itself, you can utilize the $this keyword to access the object itself. Alternatively...
public static function getInstance() {
if(!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
Where instance would be a private member variable. Make sure your constructor is private so that your object cannot be instantiated externally. <--- all this assuming php5.
I think you can do self->save($this), if save is a class method, or just save($this) if save is an instance method.
Anyway, the point is $this refers to the current instance. So setName is acts on an instance of user, so $this should equal that user inside of setName.
Is there any way to call a php class (eg. $var = new className) and have var store the value returned by the className function?
Or, is there a way to call a class and not have it execute the function with the same name?
The function of the same name as the class was they way 'constructors' in php 4 worked.
This function is called automatically when a new object instance is created.
In php 5, a new magic function __construct() is used instead.
If your using php5 and don't include a '__construct' method, php will search for an old-style constructor method.
http://www.php.net/manual/en/language.oop5.decon.php
So if you are using php5, add a '__construct' method to your class, and php will quit executing your 'method of the same name as the class' when a new object is constructed.
It is possible in PHP5 using magical method __toString(); to return a value from the class instance/object.
simply
class MyClass{
function __construct(){
// constructor
}
function __toString(){
// to String
return 5;
}
}
$inst = new MyClass();
echo $inst; // echos 5
Constructors don't return value (in fact you can't do that). If you want to get a value from the instance of the class, use the __toString() magical method.
Constructors don't return values, they are used to instantiate the new object you are creating. $var will always contain a reference to the new object using the code you provided.
To be honest, from your question, it sounds like you don't understand the intention of classes.
$var = new classname will always return an instance of classname. You can't have it return something else.
Read this...
http://www.php.net/manual/en/language.oop5.php
Is it ok to use a singleton method inside of a __constructor to initiate the class if it wasn't already?
No -- A singleton method is an alternative to using a constructor.
Instead of saying $session = new Session();
you should say
$session = Session::getStaticSession();
Then define Session::getStaticSession() as a function tht returns an internal static var, and calls "new Session()" if the internal static var is null.
If you create it in each constructor that uses it, then it isn't a singleton.
If you follow this tutorial then it should help you understand how to use the singleton design pattern in php.
http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729/page1.html
You can't use a singleton method inside a constructor, as the object has already been created, and you can't return anything. Your singleton method, on the other hand, needs to either return the current object or create a new one.
You can use a single method to do that, however, such as the following:
<?php
class X {
// ...
function instance() {
static $instance;
if(!is_a($instance, 'X')) {
$instance = new X();
}
}
?>