Object become "non object" when trying to access methods or properties - php

I'm having some trouble trying to write a plugin for CraftCMS (a CMS based on YII Framework). I'm trying to create a simple fieldtype that I'm going to use inside a matrix block.
So far the public funciton getInputHtml of my fieldtype class, contains only a
var_dump($this->element)
And it shows me, as expected:
object(Craft\MatrixBlockModel)#1121 (25) {
["elementType":protected]=>
string(11) "MatrixBlock" [.......]
The problem is that, as I try to change the previous
var_dump($this->element)
with a
var_dump($this->element->getOwner())
(or any other method/property of the MatrixBlockModel class), I obtain:
"Call to a member function getOwner() on a non-object"
The only think I thought is that it could have something to do with the magic method __call() overwritten in a class from which MatrixBlockModel inherit (actually, a parent of a parent of a parent...). But, trying to have a look to its code, it do not seem so.

It likely is something with __call as you suggest. What happens if you do:
$var = $this->element;
var_dump($var);
var_dump($var->getOwner());
I have a hunch that if you assign it to a temporary variable that might solve the issue.

Related

Filepath of File Where SRO Method was Called

I have a class:
Class General
{
...
}
And I am accessing a method, like this, from another file:
General::the_method($params);
Is there a way to determine, from WITHIN the class, the filepath of WHERE the method was called? Not the filepath of the General class, but of the separate function, prbably many folders away, that has called the method?
I've tried ReflectionClass::getFileName(), however it seems this only works on fully instantiated objects (ie, if I'd done $general = new General, which I don't want to do). I figured it wouldn't work given the description of the functionality but I thought I'd give it a try. No dice, sadly.
So: is this possible?
EDIT: We are trying to accomplish this WITHOUT a second parameter passed to the function.

Anyone know of a PHP Magic Constant for Trait's Redefined Name in a Class?

To make it simple, I have noticed that PHP doesn't seem to offer any magic constant for determining what the name that a trait has been changed to in a class. Since this sounds confusing to me in words, I will give an example, as it is rather easy and would expect it to be somewhere in the new PHP 5.5, I don't see a way to doing it. So here it is:
Say we have some class, that uses some trait that conflicts with some function inside the class, example:
class SomeClass {
use \Name\Space\SomeTrait { SomeFunction as private NewFunctionName; }
function SomeFunction() {
$this->NewFunctionName();
}
}
Since, obviously this class has the "SomeFunction" function, and we are aware that inside of SomeTrait we have included, is a function that is matching by name to a function we have inside this class. Now, since the "SomeFunction" came into this class via a trait inside of a \Name\Space, these 2 functions do 2 different things, but happen to use the same name, and inside of either another function or literally our 'SomeFunction', we then use the "SomeFunction" from our trait, by calling it by the "NewFunctionName".
So hopefully I haven't lost anyone here, as here is what my question comes down to in the above scenario. Within the \Name\Space\SomeTrait\SomeFunction(), how could one get the "NewFunctionName" that this trait function was assigned too? One would think to use a magic method, such as __FUNCTION__, or __METHOD__, or even __TRAIT__, except none of these give the expected result, so does anyone know a way to get this information without passing it to the function as a parameter and resulting in a hacky code? Maybe PHP 5.6 needs to add a new Magic Constant __AS__, or adjust the result of __TRAIT__, I dont understand why __TRAIT__ and __FUNCTION_ need to return the same information (or nearly the same information). Any help would be awesome, if it is an unconventional hacky method, Im interested in seeing my options, until I can open up a bug report with php regarding this. (if it is truly a bug)
edit:
My current, least hacky, method seems to be,
debug_backtrace()[0]['function']
and though it works, I feel it is doing a lot to get a simple string, especially if you use the function a lot. :/
This is the solution I ended up using. It's not very good but probably better than using the debug_backtrace function.
Problem example:
Trait ExampleTrait {
protected function doSomethingRecursive() {
// this is a problem because it could be renamed
$this->doSomethingRecursive();
}
}
Solution example:
Trait ExampleTrait {
protected function doSomethingRecursive() {
// this is a problem because it could be renamed
$this->__internal_doSomethingRecursive();
}
private function __internal_doSomethingRecursive() {
// this works because the class would have
// used and renamed the above function
// but this "internal" function *should*
// remain available under it's original name
$this->__internal_doSomethingRecursive();
}
}
Of course it's possible to break this but for most cases it should be fine. You could also include the name of the trait in the internal function name to further prevent conflicts.
Your current solution is going to be the best, with a couple tweaks:
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,1)[0]['function']
The DEBUG_BACKTRACE_IGNORE_ARGS and the frame limit of 1 there will make the backtrace shallow, faster, and use less memory.

Can PHP class contain method not listed by function `get_class_methods` ? If so, how? If not, why does it appear to?

I am digging into some Magento code.
I'm looking at class Mage_Catalog_Model_Session
There is code in class Mage_Catalog_Block_Product_List_Toolbar extends Mage_Core_Block_Template function getCurrentOrder like this:
Mage::getSingleton('catalog/session')->getSortOrder();
Now, Mage::getSingleton('catalog/session') returns an object of type Mage_Catalog_Model_Session
So I would think that getSortOrder() is a method of that class, although the method seems like it would go with this toolbar class and not that session class.
This line should give me the list of methods of the class:
print_r(get_class_methods(get_class($_test)));
And it does seem to, but getSortOrder() is not listed.
So, which class is getSortOrder() a member of and how is it that it either A.) appears to be a member of a class it's not a member of, or B.) is a member of that class but does not appear in the get_class_methods() result set?
Sounds like getSortOrder() is an overloaded method. See here for more info on overloading. Taken from the link:
Overloading in PHP provides means to dynamically "create" properties and methods.
get_class_methods() wouldn't display overloaded methods because they are created on the spot when called (And therefore there's no way to know about them.) A lot of frameworks use overloading for getters.
Btw, see this answer for an example of how overloading a getter would be achieved.

Calling overridden method from within overriding method in OO PHP

Working in a symfony model, I want to override a function and call the overridden function from within the overriding one, along the lines of
class MyClass extends BaseMyClass {
function setMyProperty($p) {
parent::setMyProperty($p);
//do some other stuff
}
}
This is resulting in a segmentation fault. I don't want to alter the parent class - it's been generated by symfony, and may feasibly be overwritten in the future if the model is rebuilt. This seems like something that should be straightforward, but I'm struggling to find the solution.
Since you saw the problem, I guess you should mark it as answered to remove it from the unanswered list.
I've managed to find a solution to my own question on the symfony project forum.
I can't call the overridden function because it doesn't exist. Though it exists enough for me to override it.
Using
$this->_set('my_property', $p);
Works where
parent::setMyProperty($p);
Causes the error.
Note that
$this->setMyProperty($p);
Works fine in my class if the method has not been overridden.

How to explain 'this' keyword in a best and simple way?

I am using 'this' keyword for a long time. But when someone asks me to explain it, I am confused that how to explain it. I know that I can use this in a method of class to access any variable and method of the same class.
class MyClass{
function MyMethod1(){
echo "Hello World";
}
function MyMethod2(){
$this->MyMethod1();
}
}
Is it a object of a class that we don't need to initialise and can be used only within the class or anything else. How to explain?
Thanks
A class is a mold for an object: it specifies how the object looks like (variables) and what it can do (functions).
If you instanciate a class: you create an object. If you create the class, you can use "this" to refer to the object itsself. This is why you can't set the "this", because it's related to the object. It's a special, read-only variable.
this references the current object instance of a class.
this is an implicitly parameter passed to the methods of a class: it is scoped to a method and allows access to all of the object's members.
Like their name suggests, instance methods operate on instances of a class. How do they know which one to operate on? That's what the this parameter is for.
When you invoke an instance method, you're really invisibly passing in an extra parameter: the object to invoke it on. For example, when you have this:
class Basket {
public function a() {
$this-> ...;
// ...
}
// ...
}
and you call $some_basket->a(), behind the scenes you're actually calling something like Basket::a($some_basket). Now a() knows which Basket you want to work with. That special parameter is what this refers to: the current object you're dealing with.
short:
$this gives you access to the object variables (and methods) Edit: within the class :) Edit 2: (but not in static methods of the class) :D
Several people have explained it in similar terms, but thought I'd add that when speaking to people unfamiliar with object oriented programming, I explain that the class definition is the blueprint, as for a house, and "this" is the actual house you're working with at that moment. There might be other houses that look exactly the same, but this is the specific object (house).
A class is a template or a 'die' for an object.
Lets use the classic 'bicycle' example. There are many huffy bikes out there. However, we have created one bike, and we can use the 'this' keyword to refer to 'this' bike.
In more a more technical sense, a class is a template for an object that will be instantiated. At run time, after an object has been instantiated, or had an instance of itself created, we can then use the keyword 'this' internally to refer to the instance that runs that method.

Categories