Is there a way to instantiate a class and call one of its methods in one line? I hoped the following would work but it doesn't:
(new User())->get_name();
I know this question is old but the replies can be misleading.
Since version 5.4 you can instantiate and call methods inline:
(new Foo())->bar();
http://docs.php.net/manual/en/migration54.new-features.php
This is not possible. You could, however, create a static method returning a new instance. Something like:
class User {
public static function create() {
return new self();
}
}
User::create()->get_name();
Nope, sorry, this unfortunately doesn't work in PHP. You could work around it by using a static factory method or something like that though.
Try if this works for you. It calls the function from the class not an object.
User::get_name();
Related
So I currently have a class and wanted to make class calls cleaner by being able to call the class instance as a function, like the __toString magic method which outputs a string when called, instead be able to call $instance() as a function and have it called.
Like:
class MyClass {
public function __onCall() {
echo 'This was called when the user called the instance!';
}
}
$instance = new MyClass();
$instance();
//opts: This was called when the user called the instance!
Essentially I want to be able to chain class functions and cut off one chain that'll be called a lot by calling a function from the instance.
Syntax I want:
$Class('Some String')->SomeFunction()->AnotherFunction();
Syntax I have:
$Class->select_string('Some String')->SomeFunction()->AnotherFunction();
:-)
Ok. I see what you mean here. So you want to have a fluent method chaining. This is actually answered by another thread
Hope this helps.
I realize this is a common question and I have tried resolving it myself, but after following instructions from other answers I can't get it to work. So, this is the issue - I need to call a method from the class ClassOne in ClassTwo. So I did this:
class ClassOne{
public function methOne($par1,$par2){
mysql_query("insert into ps_loyalty_events (customer_id,event_id) values ('$par1','$par2') ") or die(mysql_error());
}
}
class ClassTwo{
private $customer; //initialize $customer in the constructor, to be defined as an instance of ClassOne() class and used as $this->customer
function __construct() {
$this->customer = new ClassOne();
}
public function methTwo(){
//some stuff here
$this->customer->methOne(6,10); //6,10 - randomly chosen parameters, irrelevant
//some more stuff here, this doesn't get executed at all
}
}
The priblem is not in ClassOne or the method methOne() because calling them directly from a regular PHP file in the following manner works:
$customer = new ClassOne();
$customer->methOne(6,10);
However, when I call it from the ClassTwo method, it does nothing - it just stops the execution of that function. Using try-catch doesn't seem to output anything. What am I doing wrong?
It's because your methTwo is static. When you call a static method of a class, that class is not instantiated into an object, and therefore it doesn't have the $this->customer property.
Unless there is a reason for the static method, you can change methoTwo:
public function methTwo(){
Edit: now that you have fixed that: what makes you think it isn't working? You don't do anything in methOne.
The code given is fine, see this Codepad demo of it working. That means there's some other code that we can't see that's causing the problem.
For simple solution, try to use extend classone in classtwo, so that all the method can user in classtwo by default
class class_two extends class_one
By above all the method of class one will be accessed into class two and can easily use that also. try it
For example, I have a class
class MyClass
{
public $something = 'base';
public function __construct()
{
$something = 'construct';
}
public function __destruct()
{
$something = 'destruct';
}
public static doSomething()
{
$return = new MyClass;
echo $return->something;
}
}
So, my question is this... Will running the static method without instantiating the object run the constructor? If I had, for example, database connection information in the constructor, could I run a static method that returns a query withing explicitly instantiating the class?
Thanks in advance
Yes the construction will be called in your example. Since you already have the code, I guess it would be easy to test.
If you execute MyClass::doSomething(), it will create object of MyClass and, of course, its constructor will be called. Why not to run it and see the result?
I'm lacking PHP knowledge, but compared to other OO languages it will of course run the constructor, because you tell the static method to create a new instance of MyClass.
The same would apply if you called a new SomeOtherType. The code itself doesn't care if it's inside a static/public/private method, as long as new is there, the constructor is invoked.
I did not ask the question correctly, but the answer is that as long as the object is instantiated, even within a static method, the constructor will run. The output would be whatever is in the constructor as the deconstructor does not fire until after the last call to the class.
Sorry for the confusion in the question.
Hi I'm a bit of a newbie to OOP, i just have a quick question: say I have a function in a class declared as
class House
{
public static function hasAlcohol()
{
// Do Something
}
}
I know i can call this as
House::hasAlcohol()
However, i would also like to know if its okay with coding standards and PHP and if it would be error free to call hasAlcohol() from an instance of house (i tried it and got no errors), for example
$house = new House();
$house->hasAlcohol();
As this has caused several problems for me in the past: Yes, it is valid code. Should you do it? No. It gives the impression that the call is non-static and will most likely cause grief for people working on your code later on. There is no reason to make your code ambiguous.
This used to be possible, but the latest versions of PHP will throw an error, if I remember correctly. You should call static functions statically. You can do $house::hasAlcohol() though.
This used to be possible, but the latest versions of PHP will throw an error, if I remember correctly. You should call static functions statically. You can do $house::hasAlcohol() though.
On a side note, should hasAlcohol really be static? From the name it appears it should be an instance method.
A more recommended pattern if you need constant access to a method is to use a static constructor and get an instance (even if it's a "blank" or "empty") instance to that class. So in the example you've shown, it might be better to have a method like this:
class House
{
public function instance()
{
return new House;
}
public function hasAlcohol()
{
// Do Something
}
}
Then if you ever needed to make a call to "hasAlcohol()" where you don't need an instance for any other purpose, you can do a one-off like so:
House::instance()->hasAlcohol();
or you can instantiate it like in your example:
$house = new House;
$house->hasAlcohol();
or, better yet, use your new factory method:
$house = House::instance();
$house->hasAlcohol();
I have a very special case in which I need to call a protected method from outside a class. I am very conscious about what I do programmingwise, but I would not be entirely opposed to doing so in this one special case I have. In all other cases, I need to continue disallowing access to the internal method, and so I would like to keep the method protected.
What are some elegant ways to access a protected method outside of a class? So far, I've found this.
I suppose it may be possible create some kind of double-agent instance of the target class that would sneakily provide access to the internals...
In PHP you can do this using Reflections.
To invoke protected or private methods use the setAccessible() method
http://php.net/reflectionmethod.setaccessible (just set it to TRUE)
I would think that in this case, refactoring so you don't require this sort of thing is probably the most elegant way to go. In saying that one option is to use __call and within that parse debug_backtrace to see which class called the method. Then check a friends whitelst
class ProtectedClass {
// Friend list
private $friends = array('secret' => array('FriendClass'));
protected function secret($arg1, $arg2) {
// ...
}
public function __call($method, $args) {
$trace = debug_backtrace();
$class = $trace[1]['class'];
if(in_array($class, $this->friends[$method]))
return $this->$method($args[0], $args[1]);
throw new Exception();
}
}
I think I need a shower.
This is a little kludgy, but might be an option.
Add a child class for the sake of accessing your protected function
public class Child extends Parent {
public function protectedFunc() {
return parent::protectedFunc();
}
}
Then, instantiate an instance of Child instead of Parent where you need to call that function.
I'm just throwing this out there since I haven't programmed in PHP in two years. Could you just add a function to the class that calls the protected method like so?
$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');
Edit:
I think Tom's correct in looking at the documentation for create_function. It looks like the scope of $this will be "wrong" when you try to call it with this example.
It looks like traditional anonymous functions are supported since PHP 5.3.0 as well (and my first solution probably won't work), so I'd probably write it like this instead:
$obj->publicFunc = function($arg) {
return $this->protectedFunc($arg);
};
Since I think it looks a little cleaner (and your IDE of choice will highlight it better of course).
Ugh, I tried using Reflection to call the method but PHP won't allow you to do that either. It seems that you're going to have to use some sort of child class like the other posters have suggested. If you find a method that works, the developers will likely classify it as a bug in the future and break your code when you upgrade to the next version.
I recommend extending the class.
I'd think about what is the matter with the program design if I have to call a private function?
It used to be the case when
your class is responsible for several things (it is really two or thre calsses wrapped together) or
the rules of encapsulation are broken (utility functions, for example)
By finding any way to walk around this questions, you'll be nowhere nearer to the real solution.
Suppose your method declaration goes like so:
protected function getTheFoo() {
...
}
protected function setTheFoo($val) {
...
}
Usage:
$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');
This bypasses the protected methods and goes directly straight to the instance variables.