Perhaps it is a very simple issue, but I'm missing something in OOP fundamentals. Suppose I have to php file, say file1 and file2. file1 implements a class from the class Class, and in some of the method of the latter, say MethodA. In MethodA, I instantiate a class say $object from the class Object (which comes from another file3), and I call a method, say MethodB that takes as an argument the instantiation $object, and processes to set the value of one attribute of the instantiation $object. So, the scheme is the following :
class Class{
public function MethodB($object){
$param
...
$object->setValue($param);
...
}
public function MethodA(){
$object = new Object;
...
$this->MethodB($object);
...
$object->getValue();
}
}
Now the problem is that I am not able to get back the value of $object->getValue($param), and the question is why?
Related
I have an object with some protected fields and a method that uses them. The method doesn't do exactly what I need it to do, but I cannot change the original code since I am writing an add-on.
Is it somehow possible to extend the class and override the method so that I could call it on predefined objects of the original class? I thought about monkey patching but apparently it is not implemented in php.
You can override a method by extending the parent class, initiating the new class instead of the parent class and naming your method exactly the same as the parent method, that was the child method will be called and not the parent
Example:
class Foo {
function sayFoo() {
echo "Foo";
}
}
class Bar extends Foo {
function sayFoo() {
echo "Bar";
}
}
$foo = new Foo();
$bar = new Bar();
$foo->sayFoo() //Outputs: Foo
$bar->sayFoo() //Outputs: Bar
I hope below stategy will be works. asume that class is Foo and method is bar(). for override bar() method you have to make customFoo class as mentioned below.
class CustomFoo extends Foo{
public function bar(){
parent::bar();
}
}
I dont know actually what you need because you dont have explained in detail. Still I have tried my best. :)
Try creating a child class that extends the base or parent class that the object currently derives from.
Create a new method with exactly the same name as the method in the Parent class and put your logic in there.
Now instantiate your object from your new class, you would have succeeded in overriding that particular method and still have access to the methods and properties of the base class.
Problem is, once you've loaded the class, you can't officially unload it, and you do need to load it in order to extend it. So it's pretty tied up. Your best bet is to either hack the original class (not ideal) or copy paste the original class definition into a new file:
class ParentClass {
//Copy paste code and modify as you need to.
}
Somewhere after the bootstrapping of your framework:
spl_autoload_register(function ($class) {
if ($class == "ParentClass") { //Namespace is also included in the class name so adjust accordingly
include 'path/to/modified/ParentClass.php';
}
},true,true);
This is done to ensure your own modified class will be loaded before the original one.
This is extremely hacky so first check if the framework you're using has native support for doing this.
I want to define a base class with static functions and an extended class which calls the static methods of its parent. As an example a base class for arrays cArray with a static method Length($arr), so a static method call
cArray::Length($myArray);
Then I want to write an extended class xArray and use it as follows:
$objArr = new xArray($arr);
$objArr->Length();
My question is whether this is ever possible. I tried many codes but all get failed for different reasons.
You should just be able to call the method statically. It will automatically call the method in the parent class, unless you have redefined the same method in the child class.
xArray::Length($arr);
To put this into code:
class cArray {
public static function Length($myArray) { ... }
}
class xArray extends cArray {
...
public function Length() {
parent::Length($this->arr);
}
}
While PHP will let you do this, it's a terrible idea. When extending classes, you should not change the method signatures fundamentally. Here you're overriding the static method cArray::Length which takes one argument with the non-static xArray::Length which takes no argument. That's a fundamentally different function and thereby a bad class structure. PHP will point this out to you if you enable strict errors.
You need to rethink your approach. There's no reason the method needs to be static in the base class and no reason it needs to change its signature in the extended class.
With learning fuelPHP, I am introduced on calling classes using scope resolution, or :: in sense. Typically, when we call a method in a class we do this ...
$myclass = new myclass();
$myclass->mymethod();
On fuel, methods are usually called in this manner ...
myclass::mymethod();
I was wondering if there are any difference between the two? Is the scope resolution is something of an update on 5.3 as well ... if not, which one is ideal, or when should I use these.
Thanks.
The scope resolution operator is used to access either class constants like ::const, static variables like ::$var or call static methods like ::method().
See http://php.net/manual/en/language.oop5.static.php
Static methods can be called without having an instance of the class they are defined in. They're defined in that class with the static keyword.
For example, one of CakePHP's static methods is defined like this:
class ClassRegistry {
// ...
public static function &getInstance() {
// ...
}
}
... which you can call like ClassRegistry::getInstance().
Without the static keyword, you'd need an instance of the ClassRegistry class to call that function.
You can read more here, especially about why using static methods in your own code can sometimes be a bad idea: http://kore-nordmann.de/blog/0103_static_considered_harmful.html
I am not sure how would myclass::mymethod(); work, since I use such syntax only when I am calling a STATIC class.
MyClass::DoSomething();
would call a static method named DoSomething()
while
$instance = new MyClass();
$instance->DoSomething();
would call the instance method.
I have not tested it but I believe you will run into an error if you do $instance::DoSomething()
I think the best way to understand why there is a static call and what it does behind the scene is to check this FuelPHP blog's entry: http://fuelphp.com/blog/2011/05/why-did-you-do-that
The obvious difference is that the first solution $myObject->myMethod() it's a dynamic call : you need an instance to execute myMethod().
In the second solution, MyClass::myMethod() is a static call. The class acts as a sort of namespace where a function belong. You don't need an instance for that.
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 was wondering why there is no $parent->function(); syntax in php, but instead we can use parent::function(); which looks like it's used inside a static class. Am i missing some php oop basics?
I admit it seems strange -- and you didn't miss anything in the manual ^^
But :
Generally, when the child class re-defines a method that's already defined in the parent class, you want the child's method to totally override the parent's one
except for __construct, I admit -- that's probably why it's said explicitly in the manual that you have to call the parent's __construct method yourself.
Generally speaking, when working with non-static methods, you'll just use $this to call methods in the same instance of either the child or the parent class ; no need to know where the method actually is.
Using parent:: works fine, even if it looks like a static call
And here's an example of code showing parent:: works fine :
class Father {
public function method() {
var_dump($this->a);
}
}
class Son extends Father {
protected $a;
public function method() {
$this->a = 10;
parent::method();
}
}
$obj = new Son();
$obj->method();
You'll get this output :
$ /usr/local/php-5.3/bin/php temp.php
int(10)
Which shows that the method in the parent class has access to $this and the properties defined in the child class.
Well, parent actually references the static parent class - there is no reason to assume there is an instantiated $parent only because there exists a $child, and even if there were, $child would not have access to $parent.
Finally, an instance where the usual class dog extends animal OOP explanations don't work! :)
Because using $parent assumes that you have actually instantiated the parent class.
If your syntax suggest worked, it would mean everytime you instantiated one object, you were instantiating 2 or more objects.
In PHP, every variable must contain a string, integer(or other numeric format), array, object, or resource. $this contains an object, and it just happens to be the object that you are currently inside.
In order to create $parent, you would have to put an object inside $parent. You parent class is technically not instantiated, so it cannot be assigned to a variable.
BTW parent::function(); has access to all of $this.
Hence, this works
class Test
{
public function test()
{
echo $this->testing_var;
}
}
class OtherTest
{
public function run()
{
$this->testing_var = "hi";
Test::test(); // echos hi
}
}
And this will error if it is used outside a class, and will tell you it should be declared static.
Test::test();