Just wondering if there is any way to dump and view the function/method definition inside the class using the Object name?
I found the way to get the class name and method name as well using an instantiated object name with this function:
public function getObjectMethods(object $obj) {
$className = get_class($obj);
//return $className;
return get_class_methods($className);
}
Also, I could access the properties in the class by using the var_dump; however, is there any way I could see the method/function definition inside the class?
Well AFAIK, there is no such function to see what code written on the function directly. (well, you can get the function line number and read the file with file_get_contents)
You could use Kint as a temporary option. It's uses reflection to deep dive into the class/object/instance.
https://github.com/kint-php/kint
Kint::dump($obj);
Related
In PHP it is possible to get a full class name via class name resolution like this:
Example:
namespace Name\Space;
class ClassName {}
echo ClassName::class;
Output: Name\Space\ClassName
This is better than using the string Name\Space\ClassName directly in the code because code introspection especially in IDEs can find an error directly.
I wonder if there is something similar for methods of a class - this would be specifically useful for callback functions.
This is how you can basically can pass a callback:
$a = function($callback,$arg) { return $callback($arg); }
$a('getInfo',5);
Instead of passing a string here (which might change), I would prefer to do something like this:
$a(MyClass::class::getInfo,5);
With I "go to declaration" click in the IDE I could go directly to getInfo plus I see errors in case with method does not exist anymore. Is there a way to achieve what I want to do here?
In fact, you work with callable type. And PHP allows setting method/function name only as a string. But if you use classes and objects you will have a different way to set callback. For example:
$a = function($callback, $arg) {
return call_user_func($callback, $arg));
}
// call a static method of the class with
// using fullname space and method name as a string
$a('Name\Space\MyClass::getInfo',5);
// call a static method of the class
// with using ::class
$a([MyClass::class, 'getInfo'], 5);
// call a method of an object
$myObject = new MyClass();
$a([$myOject, 'getInfo'], 5);
Three possibilities.
(1)
echo `__CLASS__`;
...returns namespace\classname as a string.
(2)
If you're trying to get the namespace\classname from another class, i.e., not the one where you're currently executing code, then I would suggest setting a public property inside each class such as:
public static $classname = __CLASS__;
which you could then access from anywhere as:
ClassName::$classname
Put it in each of your classes. Always use the same property name.
(3)
Have you considered the PHP function debug_backtrace() which returns a call stack with the most recent call at index = 0;
So, if:
$caller = debug_backtrace();
Then, $caller[0]['class'] contains the fully qualified class name, including any namespace, at the point where you called debug_backtrace().
I'm guessing that #2 is the solution that will work for you.
Just thought of a 4th possibility that doesn't depend on you adding any code to each class. Might add some overhead though, but so does my 3rd solution above.
(4)
$declared_classes = get_declared_classes();
This lists all of the classes currently declared within the PHP scope as fully qualified namespace\classname. You could search the returned array for partial string matches within the array and return the whole namespace\classname string.
One thing to keep in mind. You might have duplicates if different namespaces have same-named classes.
I've added this as a comment somewhere else but figured it might warrant an actual answer to this question. If you use:
$callback = [MyClass::class, 'myMethod'];
Then at least one IDE (PhpStorm) will recognize this as the callable that it is, allow you to navigate to it, mention it in "show usages" and automatically change it when it is renamed through a refactor. I use this in my code if, for instance, I reference a method in a test:
$this->mock(MyClass::class, function(MockInterface $mock) {
$mock->shouldReceive([MyClass:class, 'myMethod'][1])->andReturn(10);
});
Not the cleanest syntax, but it's workable.
I apologize if this question doesn't make a lot of sense; I'm having a little bit of trouble putting it into words. I'm still learning a lot about PHP and I don't have the vocabulary down quite yet.
I have a class that has a method that accepts a different class object as it's only parameter:
class myClass {
protected $name;
public function getName() {
return $this->name;
}
public function myMethod($string) {
// Do something
}
}
I would like to be able to do something like this:
$myObject = new myClass();
$myObject->myMethod($myObject->getName());
without using the variable name of the object's method that is being passed in to myMethod(). In my head, that would work something like this:
$myObject->myMethod($this->getName());
but it doesn't. Any suggestions? Is this even possible?
That's not possible because $this exists only withing the class and represents its object. If you have class Person and inside you have $this, that means it is a reference to current Person object. But if you have outside of any class, that represents nothing.
You just cannot. You need to refer object variable explicitly.
You could make your proposition here https://wiki.php.net/rfc/howto to force syntax changing.
I have a class with property transof
class translator {
public function transof($phrase) { gives translation of phrase }
}
Now I want to pass an instance of translator to a function:
function parse($part,$class) {
$class->transof($part);
}
$tr = new translator("project","en");
parse("exception",$tr);
Do anyone know how to do this?
I know this example is to simple, and can be easily written without the use of a function, but in my real world example I would like to be able to use a function.
Of course I can use global $tr in the function, and use it inside the function, but I don't like using global.
Thanks in advance
If you do not want to create object in global code to have better maintainability then you need to modify the signature of the function as follows:
function parse($part,$project,$lang) {
$class = new Translator($project,$lang);
$class->transof($part);
}
parse("exception","project","en");
It does what you intend, the object is passed to the function parse. All you need to do is to include the class definition file in or before the php file which contains parse definition or get use of __autoload() function which will include class definition when needed.
You can also define parse this way:
function parse($part, translator $class) {
$class->transof($part);
}
Then code editors as Aptana etc. will know what class this object is an instance of and will be able to provide you with hints concerning your class structure.
i'm php coder, trying to get into python world, and it's very hard for me.
Biggest enjoy of static methods in php is automatic builder of instance. No need to declare object, if you needed it once, in every file (or with different constructor params , in one line)
<?php
class Foo {
function __constructor__(){
$this->var = 'blah';
}
public static function aStaticMethod() {
return $this->var;
}
}
echo Foo::aStaticMethod();
?>
we can call constructor from static method don't we? and we can access everything in class as it would be simple method ... we can even have STATIC CONSTRUCTOR in php class and call it like so: Object::construct()->myMethod(); (to pass different params every time)
but not in python???? #staticmethod makes method in class a simple function that doesn't see totally anything ??
class socket(object):
def __init__(self):
self.oclass = otherclass()
print 'test' # does this constructor called at all when calling static method??
#staticmethod
def ping():
return self.oclass.send('PING') # i can't access anything!!!
print Anidb.ping()
I can't access anything from that god damned static method, it's like a standalone function or something like this..??
Maybe I'm using the wrong decorator? Maybe there's something like php offers with static methods in python?
1) Please tell why static methods is isolated
2) Please tell me how to make the same behavior like php static methods have.
3) Please tell me alternative practical use of this, if php static methods behavior is a bad thing
P.s. the goal of all this to write totally less code as much as possible.
P.p.s Heavy commenting of sample code is appreciated
Thank you.
static methods in PHP are not as you believe, they can't access to instance members. No $this! with them.
<?php
class Foo {
public static $var = 'foo ';
function __construct(){
echo 'constructing ';
$this->var = 'blah ';
}
public function aMethod() {
return $this->var;
}
public static function aStaticMethod() {
#return $this->$var; -> you can't do that,
# $this can be accessed only in instance methods, not static
return self::$var;
}
}
$foo = new Foo();
echo $foo->aMethod();
echo Foo::aStaticMethod();
?>
Python has three kind of methods in objects static methods are like functions defined ouside classes, the only use to put them in object is to keep them with the class as helper functions. class methods can access only to variables defined in the class (decorator #classmethod). This is more or less what PHP calls static members or methods. The first parameter of such methods sould be cls, and content of class can be accessed through cls. Normal methods must get self as first parameter and are the only ones to be able to access to instance members.
If you want several objects of the same type you definitely need instances, and the other types are not what you are looking for. If you only have one instance of an object, you could use class methods instead (or PHP static methods).
But in most case you should not bother doing that if you don't know why and just stick with instances of objects and normal methods, doing otherwise is premature optimization and your code is likely to bite you later because of the many restrictions you introduce.
You want classmethod instead. That provides the class as the first argument.
EDIT:
class C(object):
foo = 42
#classmethod
def printfoo(cls):
print cls.foo
C.printfoo()
I see you've already accepted another answer, but I'm not sure that it will work with your code. Specifically, the oclass variable is only created for instances of the class, not for the class itself. You could do it like this:
class socket(object):
oclass = otherclass()
#classmethod
def ping(cls):
return cls.oclass.send('PING')
socket.ping()
However, using your existing code and removing all decorators, you could simply instantiate it and use a method on the same line:
socket().ping()
i m learning OOPS with JOOMLA... here sometimes i found difficulties to find the method used in some class...
is there any way to find that this function is declared on this class or useful information about that function??
for exmaple
class testModeltest extends JModel
{
function modifyCategory($data = array())
{
$image = $this->imageResize($value);
.......
}
}
now i want to know where the imageResize() function declared/defined first time...means class and file name where this function born
i used magic constact __METHOD__ this retrive useful information inside class . i need such type of function where i just put method name & i get the complete information of that function
i want a below kind of facility( i m sure there are some function in php to get the information about class but don't know )
functionInfo($methodname) // here i just put the function name
which return
Function Name:imageResize
Main class : imageclass
File name where it has been declared : /foldername/filename.php
currenty using(called) in : thisclass::this function
If you are looking for the place where a method was first defined, that should be possible using get_parent_class() - here is a snippet that walks through each class definition - and doing a method_exists() on each class found that way.
However, this will not show where the method has been subsequently overriden, so it may be of limited use to you - in that case, something like Reflection is probably indeed the only way.