Was something()->Something always valid php? Is this fine to use? - php

Examples I have seen for my thing first put this into a variable. It pulls in a lot of data. A object I guess. But i just need one little piece of it.
$data = something();
echo $data->Something;
I just tried this never seen this in any php code and just tryed. Is this something always worked even in ond php versions? Is nobody doing it for a reason, or did I just not saw enough code??
echo something()->Something;
It works fine.

Referencing an object property from the return of a function has been supported since PHP introduced classes (PHP version 5.0.0).
This can be demonstrated with the following simple test case:
class Something {
public $foo;
}
function get() {
$obj = new Something;
$obj->foo = 'bar';
return $obj;
}
echo get()->foo;
This will print bar on every PHP version >= 5.0.0.

Related

PHP: class variable visibility

I'm just a once-in-a-while PHP developer. Now, working on a legacy application, I just hit upon the following problem, which seems very stupid. But I can't get $someString class variable to hold the right value:
class MyClass{
var $someString;
function doSomething(){
//$this->setString(); //this is effectively not called here, but later in getIframe()
$this->buildIframe();
echo $this->someString; //actually, I need someString here, but it is empty
}
function setString(){
$this->someString = "something";
}
function buildIframe(){
$content .= <iframe....>;
}
function getIframe(){
$this->setString();
}
}
$myClassInstance = new MyClass();
$myClassInstance->doSomething();
$myClassInstance->getIframe();
As far as I can see, doSomething() is called in a class context, as I did show.
What am I doing wrong?
EDIT:
I reviewed the code and I think I found whats causing this. There is an iframe embedded into the html output, which is generated at one part and called later on. So the setString() method is actually not called imediately, what I thought first but when invoking the iframe code. So thats why it's not available where I need the string output.
I guess like the code is now, there is no way to get the $someString output except inside the getIframe() method.
This code is 100% correct and working. I've checked it on PHP 5. It echos "something" in string. And it is proper behavior.
From manual:
Note: The PHP 4 method of declaring a variable with the var keyword is still supported for compatibility reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its usage would generate an E_STRICT warning.

PHP dynamic class names with static functions

I found some strange PHP behaviour, I'm interested if someone could explain me why some parts of this code works, while others don't.
PHP can create new classes dynamically when class names are stored in variables. And it works fine since I'm using a modern version of PHP (5.5.28). But I found some strange behaviour that I don't really understand.
The problem occurs when the class name is stored in a property of some object. In this case, static functions cannot be called on the dynamic class:
$this->dynClass::SomeFunction() fails and ($this->dynClass)::SomeFunction() fails as well. However $instance = new $this->dynClass works. So if I need to call a static method on $this->dynClass, I have to create a local variable storing the same string: $tmp = $this->dynClass. And then, I can call $tmp::SomeFunction()
I really don't understand this. Could this be a bug? Please someone explain me.
Here's my example code:
<?php
class MyClass {
static function SomeFunction($name){
echo "Hello $name\n";
}
}
MyClass::SomeFunction("World"); //Works fine as it should, prints Hello World
$firstInstance = new MyClass;
$firstInstance::SomeFunction("First"); //prints hello first, no problem
//here comes the interesting part
$dynClass = "MyClass";
$dynClass::SomeFunction("Dynamic"); //Yeah, it works as well
$secondInstance = new $dynClass;
$secondInstance::SomeFunction("Second"); //Hello Second. Fine.
//And here comes the part that I don't understand
class OtherClass {
private $dynClass = "MyClass";
public function test(){
$thirdInstance = new $this->dynClass; //WORKS!
$thirdInstance::SomeFunction('Third'); //Hello Third
//BUT
$this->dynClass::SomeFunction("This"); //PHP Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
//OK, but then this one should work:
($this->dynClass)::SomeFunction("This"); //same error. WHY??
//The only solution is creating a local variable:
$tmp = $this->dynClass;
$tmp::SomeFunction("Local"); //Hello Local
}
}
$otherInstance = new OtherClass;
$otherInstance->test();
?>
Before the Uniform Variable Syntax, php's variable parsing was basically a big lump of corner cases.
In particular, certain operations, like ::, where not supported on (...) expressions.
The two errors you encountered are examples of this loosely defined and inconsistent variable parser.

In PHP, how to quickly access objects property from a return?

My problem is this.
A function return an object, and I want to access its property. It throws and error when I try to do it like this
$this->FunctionThatReturnsAnObject()->Property;
Right now I'm creating a new variable and taking the property from it, like this:
$newVar=$this->FunctionThatReturnsAnObject();
$property=$newVar->Property;
Is this the right way of doing this?
This works perfectly fine in modern PHP versions.
[mcg#mcg-workstation ~]$ php -a
Interactive shell
php > class Foo { public function functionThatReturnsAnObject() { return new Bar(); } }
php > class Bar { public $property = 'Hello, world.'; }
php > $f = new Foo();
php > echo $f->functionThatReturnsAnObject()->property;
Hello, world.
php >
If you're experiencing an error, we'll need to know what the error is. As mentioned in the comments, you might not be able to do this in PHP4, but you shouldn't be using PHP4 in the modern era to begin with. As long as the instance method you're calling returns an object, you can operate on that object directly. (You can't do this from a constructor right now: new Foo()->functionThatReturnsAnObject() will not work because the PHP internals team is full of people that think this would be confusing in some way. I'm not making this up.)

How do I reference PHP functions?

I'm making a plugin system. I have a class extensionmanager that takes the name of a plugin as a constructor parameter. Long story short, this is the code I'm trying to run:
$this->parsedata = function($data) {
$this->extension::parsedata($data);
};
$this-extension is a string with the name of the plugin. I have run static functions in the exact way shown in this example before. Now I'm getting the error unexpected T_PAAMAYIM_NEKUDOTAYIM on that second line (I've heard it roughly translates to "unexpected double colon")
Could anyone help me understand why?
Before the above example I tried to run something like this
$this->parsedata = &$this->extension::parsedata;
Hence the question title. The top example I thought was closer to working so I changed it.
call_user_func may give you a solution. Somewhere in the examples you have this code :
<?php
namespace Foobar;
class Foo {
static public function test() {
print "Hello world!\n";
}
}
call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0
call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); // As of PHP 5.3.0
?>
I think you can easily adapt this to call your static function. For example something like :
call_user_func(array($this->extension, 'parseData'), $data);
Do that:
$self = $this;
$this->parsedata = function($data) use ($self) {
{$self->extension}::parsedata($data);
};
Yet, I would suggest to avoid static functions. After all, whoever is going to use your extension manager will need to conform to some interface. Why not take advantage of abstract methods or interfaces to make the user conform to your interface?

return var doesn't work when var is huge?

So I am using PHPExcel (http://phpexcel.codeplex.com/) to import a excel sheet. everything works fine on my development system, BUT it doesn't quite work on the live system.
Hence I debugged and looked what could be wrong. I got to a point where I found that a method obviously returned NULL, where it should have returned an object. I looked into that method, and var_dump()ed the var which was returned in the method. the var was NOT NULL
PSEUDO CODE:
class Bar()
{
function methodInAClass()
{
$test = new Foobar;
[...]
/* $test was an object here with a lot of data (var_dump()
* took around 100.000 lines in an editor) */
var_dump($test);
return $test;
}
}
$bar =& new Bar();
$test2 = $bar->methodInAClass(); //$test2 is NULL here
What am I doing wrong? Is this a problem that comes from the php.ini?
A higher memory limit seems to have fixed the issue!
PHP shouldn't care how big the returned value is if it's the actual object being returned (as it is in this case). More explicit detail might help, because your quoted example should work without issue... I have some familiarity with PHPExcel. What version are you using? What object are you returning? (IIRC there isn't a Foobar object in the library) Are you using any memory caching?
I see no reason for this happen. Unless you're doing something funny you're not showing us, I don't see how you could check this out without a native debugger, where you could, for instance, put a data breakpoint on the contents of the object.
And by the way, there's no reason you should do $bar =& new Bar(); instead of $bar = new Bar(); (in PHP5); in fact, the former is deprecated.

Categories