how to call public static function of class from different namespace in php. I have this code:
namespace x\y\z;
use x\y\z\h\Foo;
...
$classinstring = 'Foo';
$classinstring::getType();
and i got error that php can't find class Foo Fatal error: Uncaught Error: Class 'Foo' not found how i can do this?
To instantiate a class, you should use new.
$classinstring = new Foo();
Writing $classinstring = 'Foo' assigns $classinstring the string literal "Foo".
Namespacing is a shortcut to your classes. These two statements are equal:
namespace x\y\z;
use x\y\z\h\Foo;
$bar = new Foo();
and
$bar = new \x\y\z\h\Foo();
Also make sure you have your class names spelled exactly the same as the file name.
Static methods do not need to be instantiated to be used; you can call them directly from the class name.
Foo::someCustomMethod();
You are using getType() as an example, although this is a native PHP global function and cannot be called as a static method, unless you have defined your own getType() method within the class.
class Foo
{
public function getType()
{
echo 'This is my own function.';
}
public static function callAnywhere()
{
echo 'You don't have to make a new one to use one.';
}
}
This is good if you need to call class methods.
Foo::callAnywhere() // prints 'You don't have to make a new one to use one.';
$bar = new Foo();
$bar->getType(); // prints 'This is my own function.'
$other = new stdClass();
echo getType($other); // prints 'object';
Try this.
namespace x\y\z;
use x\y\z\h\Foo;
...
$classinstring = 'Foo';
$classinstring = new $classinstring;
$classinstring::getType();
OR
Maybe your file just could not find and access the class x\y\z\h\Foo. Make sure that your class Foo has the namespace of namespace \x\y\z\h.
Related
I have derived a class from Exception, basically like so:
class MyException extends Exception {
private $_type;
public function type() {
return $this->_type; //line 74
}
public function __toString() {
include "sometemplate.php";
return "";
}
}
Then, I derived from MyException like so:
class SpecialException extends MyException {
private $_type = "superspecial";
}
If I throw new SpecialException("bla") from a function, catch it, and go echo $e, then the __toString function should load a template, display that, and then not actually return anything to echo.
This is basically what's in the template file
<div class="<?php echo $this->type(); ?>class">
<p> <?php echo $this->message; ?> </p>
</div>
in my mind, this should definitely work. However, I get the following error when an exception is thrown and I try to display it:
Fatal error: Cannot access private property SpecialException::$_type in C:\path\to\exceptions.php on line 74
Can anyone explain why I am breaking the rules here? Am I doing something horribly witty with this code? Is there a much more idiomatic way to handle this situation? The point of the $_type variable is (as shown) that I want a different div class to be used depending on the type of exception caught.
just an example how to access private property
<?php
class foo {
private $bar = 'secret';
}
$obj = new foo;
if (version_compare(PHP_VERSION, '5.3.0') >= 0)
{
$myClassReflection = new ReflectionClass(get_class($obj));
$secret = $myClassReflection->getProperty('bar');
$secret->setAccessible(true);
echo $secret->getValue($obj);
}
else
{
$propname="\0foo\0bar";
$a = (array) $obj;
echo $a[$propname];
}
Name the variable protected:
* Public: anyone either inside the class or outside can access them
* Private: only the specified class can access them. Even subclasses will be denied access.
* Protected: only the specified class and subclasses can access them
See my answer here:
https://stackoverflow.com/a/40441769/1889685
As of PHP 5.4, you can use the predefined Closure class to bind a method/property of a class to a delta functions that has access even to private members.
The Closure class
For example we have a class with a private variable and we want to access it outside the class:
class Foo {
private $bar = "Foo::Bar";
}
PHP 5.4+
$foo = new Foo;
$getFooBarCallback = function() {
return $this->bar;
};
$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo');
echo $getFooBar(); // Prints Foo::Bar
As of PHP 7, you can use the new Closure::call method, to bind any method/property of an obect to a callback function, even for private members:
PHP 7+
$foo = new Foo;
$getFooBar = function() {
return $this->bar;
};
echo $getFooBar->call($foo); // Prints Foo::Bar
You need to set the access to protected. Private means that it can only be accessed from within it's own class and can't be inherited. Protected allows it to be inhherited but it still can't be accessed directly from outside the class.
If you check the visibility documentation, buried in a comment is:
// We can redeclare the public and protected method, but not private
You should make it protected to do what you're trying to do.
Incidentally, it looks like you're just setting it to be the class name - you could just use get_class():
<div class="<?php echo get_class($this); ?>class">
You should indeed change the accessmodifier to protected when you'e builing inheritance classes.
One extra point though; don't use return ""; but just use return;
Cannot access $this outside of a class.
Instead, need to call an instance of the class.
Then, access a function within the class which will return the message.
There is this way by using \Closure :
$reader = function ($object, $property) {
$value = \Closure::bind(function () use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
$myClass = new MyClass();
$property = $reader($myClass, 'yourProperty');
echo $property; // will display the value of property
I have a class setup like this:
class myClass {
public function __construct() {
echo 'foo bar';
}
}
To run it, I can simply do:
$object = new myClass;
Is there any way to run the class so __construct initiates without creating a new variable with the class object.
For example, a basic function can be run with:
functionname();
Don't call __construct directly. If you need something in the constructor to occur but you don't want an object created as a result, then use a static method.
class Thing{
public static function talk(){echo "I talk";}
}
Thing::talk(); // 'I talk'
Static methods can be called without the need for an object instance of the class.
__construct is part of a special group of methods in PHP, called Magic Methods. You don't call these directly, but PHP will call them when some event occurs. For instance when you call new on a class, __construct is executed.
Another example: if you try to get a property that doesn't exist, __get will be executed (if found):
Class Thing{
public property $name = 'Berry';
public function __get($propertyName){
return "$propertyName does not exist!";
}
}
$t = new Thing();
echo $t->name; // 'Berry'
echo $t->weight; // 'weight does not exist!';
You can try something like this if you want to avoid static:
(new MyClass)->myFunction();
I have no idea why you need this but you don't need to create a variable. You can just create object without store it anywhere.
class myClass {
public function __construct() {
echo 'foo bar';
}
}
new myClass();
In this case only the constructor will be call.
I have a woocommerce plugin that has a class Foo:
function wc_foo_init(){
class WC_Foo extends WC_Shipping_Method{
$var=get_option(); //gets an option for this session
function sayHello(){
echo $var;
}
new WC_Foo();
}
I want to call sayHello() out of the Foo class:
function bar(){
WC_Foo->sayHello();
}
But I get this error:
Fatal error: Call to a member function `sayHello` on a non-object.
You must instantiate class before make call of its methods:
$foo = new WC_Foo();
$foo->sayHello();
or if your php version is greater than 5.4 you can do:
(new WC_Foo())->sayHello();
Use $this selector if you are calling the method within the class
function bar(){
$this->sayHello();
}
If you want to call the method from other place,
you need to instantiate the class like this:
$object = new WC_Foo();
$object->sayHello();
Or make the method static like this:
public static function sayHello(){
echo "Hello";
}
And call it like this:
WC_Foo::sayHello();
// this way you dont need $object = new WC_Foo();
This might not be the full code, so it's pretty weird what you have there, but let's go.
Since you have a function to init your object, you would probably want to at least return that instance. This code might help you understand:
function init_foo(){
class foo{
function say(){
echo 'hello';
}
}
$foo1 = new Foo();
return $foo1;
}
function bar($foo3){
$foo3->say();
}
$foo2 = init_foo();
bar($foo2);
So, first we create the object and return it. Then we inject it in the bar function, just needing to call the method after that. (I used different var names so it's easier to understand scope)
I'm trying to get the following to work, but I'm at a loss...
class Foo {
public $somethingelse;
function __construct() {
echo 'I am Foo';
}
function composition() {
$this->somethingelse =& new SomethingElse();
}
}
class Bar extends Foo {
function __construct() {
echo 'I am Bar, my parent is Foo';
}
}
class SomethingElse {
function __construct() {
echo 'I am some other class';
}
function test() {
echo 'I am a method in the SomethingElse class';
}
}
What I'd like to do is create an instance of the SomethingElse class within the class Foo. This works using =&. But when I extend class Foo with class Bar, I thought that the child inherits all the data attributes and methods from the parent class. However, it seems that $this->somethingelse doesn't work in child class Bar:
$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class
$bar = new Bar(); // I am Bar, my parent is Foo
$bar->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object
So, is it not possible to inherit in such a way? And should I create a new instance of class SomethingElse from within class Bar if I want to use it there? Or am I missing something?
Thanks in advance for your help.
I thought that the child inherits all the data attributes and methods from the parent class.
This is true - the child class inherits the static variables and static methods from the parent class. Additionally, any child objects will inherit the static and instance variables and methods.
One possibility to get what you want with your existing class structure is this:
$bar = new Bar();
$bar->composition();// here you are calling the parent method, sets instance var $somethineelse
$bar->somethingelse->test();// now you can call methods
Another way to accomplish inheriting an variable (in this case an object) in child instances would be like so:
class Foo {
protected $somethingelse;
public function __construct() {
$this->somethingelse = new SomethingElse();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
// now i've got $somethingelse
}
}
For a very good overview of classes and objects in PHP 5, take a look here:
http://php.net/manual/en/language.oop5.php
Make sure to read it all, maybe a couple times if OO is new for you.
bar has a member variable named somethingelse, which is inherited from foo.
you are mixing object and class scope.
if you really want to achieve the effect described, you have to make your variable static, so its context is class based
First, you have to distinguish between static and instance variables. Static variables are shared among all instances of a class, instance variables are not.
If you want every instance of Foo and Bar to have the exact same SomethingElse-Instance you have to make $somethingelse static:
public static $somethingelse
and you should change the composition-function of Foo:
function composition() {
self::$somethingelse = new SomethingElse();
}
To access this static field you can do the following:
$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
Foo:$somethingelse->test(); // I am a method in the SomethingElse class
$bar = new Bar(); // I am Bar, my parent is Foo
Bar::$somethingelse->test(); // I am a method in the SomethingElse class
If you want every instance of Foo and Bar have their own SomethingElse instance you can use your code, but you need to add
$bar->composition()
before $bar->somethingelse->test();
That's because with
$bar = new Bar();
you created a completely new instance of Bar and that instance has a $somethingelse property, but it has not been set yet. So you need to call composition() to set it.
If every Foo and Bar should have the exact same SomethingElse-instance, you should use the static version instead, because it reduces the memory needed.
I hope this can help you. Otherwise I am very happy to explain it further.
Saying that classes share attributes doesn't mean that the objects share attribute values.
As others have noted, you are confusing classes with instances.
Note, you'd get the same error if you did:
$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class
$foo2 = new Foo(); // I another Foo
$foo2->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object
Think of the classes less abstractly. For example, you might have a class, "Person," which is a parent class of "Royalty."
Then if you did:
$me = new Person();
$me->firstName = "Thomas"
$princeCharles = new Royalty();
You wouldn't want $princeCharles to have the a firstName attribute equal to "Thomas," and if you want to set $princeCharles->firstName, you don't that to change the value of the firstName attribute of $me.
Both $me and $princeCharles have an attribute 'firstName', but we don't share the value of that attribute.
I think your problem will be solved if in the derived class constructor will call the parent class constructor. This does not occur by default in PHP so keep it in mind when you have issues with inheriting data members.
class Bar extends Foo {
public function __construct() {
parent::__construct();
}
}
In a nutshell: how do I access the methods of a class that is instantiated by a method of a different class?
There is a bit of code I am looking at right now that does the following (altering the code is not an option, btw. It isn't mine... I'm just decipher it):
A class has a method that instantiates a different class. It looks something like this:
// this file is named fooClassHere.php
class Foo{
public $meh;
function bar(){
$something = new Baz;
$this->meh = $something->getStuff();
}
}
What I am trying to figure out is how to access the methods of this instantiated class Baz. Another page contains something like the following:
include 'bazClassHere.php';
include 'fooClassHere.php';
$a = new Foo;
$a->bar();
So shouldn't all of Baz be available now in some manner (and not just getStuff() which I assigned to $this->meh)? The Foo and Baz classes are included, the code instantiates Foo and then calls Foo's method bar() which in turn instantiates the Baz class. Obviously the following will display data returned by Baz's getStuff() method:
var_dump($a->meh);
But I'd like to access all of Baz's available methods without going through the intermediate step of manually assigning them like I did inside Foo's bar method: $this->meh = $something->getStuff()
Maybe something like (but of course this doesn't work):
$a = new Foo;
$a->bar(); //instantiates Baz as $something
$a->something->fromBaz(); //$something is an instance of Baz, yes? No?
I hope this makes sense and I didn't confuse the issue with my notes. Ack! >_<
If altering the code is not an option, you're out of luck. To achieve what you want you do this:
class Foo {
public $meh;
public $something;
function bar(){
$this->something = new Baz;
$this->meh = $this->something->getStuff();
}
}
And then later on you can do:
$foo = new Foo;
$foo->something->myBazMethod();
You could use __call on your Foo class, look it up on php.net
Basically, __call gets called when you try to call a function that the class doesn't have. In there, you could pass the request to your inner object instead.
class a
{
protected $b;
public function __construct()
{
$this->b = new b();
}
public function meh()
{
return 'meh';
}
public function __call($func, $param)
{
return call_user_func_array(array($this->b, $func), $param);
}
}
class b
{
public function yo($something)
{
return $something;
}
}
$a = new a();
echo $a->meh();
echo $a->yo('dude!');