Why I need to use parent::initialize() on initialize method from Controller, although it works without this?
using: cakephp 3
Thanks
These are php OOP basics: http://php.net/manual/pl/keyword.parent.php
You may find yourself writing code that refers to variables and functions in base classes. This is particularly true if your derived class is a refinement or specialisation of code in your base class.
Instead of using the literal name of the base class in your code, you should be using the special name parent, which refers to the name of your base class as given in the extends declaration of your class. By doing this, you avoid using the name of your base class in more than one place. Should your inheritance tree change during implementation, the change is easily made by simply changing the extends declaration of your class.
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
If you need to call is up to your implementation. However, in a framework it is most of the time a good idea to call parent methods when overriding methods, to make sure the logic up in the chain is called. Read the php manual, it comes with examples.
Related
I have create one abstract class and declare two public functions and one abstract function.
After that I have created body for public function in abstract class but when I extending this class to Another class what the method body does not call then I want to know what is use of public methods with body class.
<?php
//declare abstract class
abstract class Test {
// declare method 1 with body
public function method1()
{
echo "hello"; //what is use of this code here
}
public function method2()
{
$this->method3();
}
abstract public function method3();
}
//extended abstract class to another class
class AnotherTest extends Test{
public function method1(){
echo "5+9"/2;
}
public function method3(){
echo 2+9;
}
public function method2()
{
echo "just for testing";
}
}
$obj = new AnotherTest();
$obj->method1();
echo nl2br("\n");
$obj->method3(9,10);
echo nl2br("\n");
$obj->method2();
?>
Writing a method body for a method of a base class provides a "default" behavior for that method on any subclasses that don't override the method.
For any (non-final) public or protected method of a base class you can do one of the following:
Accept that default behavior without modification by not defining a method with the same name in a subclass
Override and wrap that behavior by defining a new method with the same name that calls parent::methodName() in a subclass
Override and replace that behavior by defining a new method with the same name that does NOT call parent::methodName() in a subclass
The major benefit of code written like this is that it takes advantage of Polymorphism to dispatch generic method calls to specific implementations. Defining a method body instead of leaving it abstract just provides a default behavior. As this is a very abstract object-oriented programming concept, it is hard to set up an example that is both simple and not trivial. Best to look at popular codebases such as the Laravel Framework or one of the various Symfony components for examples of this concept in action.
Generally speaking you would not normally override every abstract method. If you are then you're doing something wrong and need to refactor.
Also, having the abstract (or any extended class) gives you the ability to call parent::function() which will let the parents method run then you can do your current classes additional logic.
In the end this is the basis for Polymorphism simple explanation a child class can extend a parent but act differently by changing how methods behave.
Bluntly your "Test" are just bad examples because in those cases you're right the abstract bodies are almost pointless.
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 have a main class that I add around a dozen child classes to similar to Example #2.
I'm wondering if there is a better way to accomplish this. I know I could do "extends" on classes (Example #1) however in order to be able to have one variable with access to all extended class functions, I'd have to "daisy chain" the extensions and then create a new class reference on the very last extension - this option is not what I'm looking for.
Example #1:
class main {
function _construct(){}
function main_function1(){}
function main_function2(){}
}
class child1 extends main{
function _construct(){}
function child_function1(){}
function child_function2(){}
}
class child2 extends child1 {
function _construct(){}
function child_function3(){}
function child_function4(){}
}
$main = new child2();
$main->child_function1();
$main->child_function2();
$main->child_function3();
$main->child_function4();
Here is what I'm currently doing.
Example #2:
<?php
class main {
function _construct(){}
function main_function1(){}
function main_function2(){}
}
class child1 {
function _construct($main){$this->main = $main;}
function child_function1(){}
function child_function2(){}
}
class child2 {
function _construct($main){$this->main = $main;}
function child_function3(){}
function child_function4(){}
}
$main = new main();
$main->child1 = new child1($main);
$main->child2 = new child2($main);
$main->child1->child_function1();
$main->child1->child_function2();
$main->child2->child_function3();
$main->child2->child_function4();
?>
Is Example #2 the best way to achieve what I'm looking for?
By doing
class child {
function __construct($main){$this->main = $main;}
}
in Example 2 you would pass the $main instance as a property for child in the constructor. In my opinion this would make sense, if $main is a container that provides information for child - which is useful if you would like to avoid having a constructor with many many arguments. According to your naming, it doesn't look like main is a container. Be aware, that you are creating a dependency between child and main then because if you want to instantiate child, you always need an instance of main in advance! What you are also doing in Example 2 is creating circular references:
$main = new main();
$main->child1 = new child1($main);
$main->child2 = new child2($main);
You would be able to call $main->child1->main then which means a high coupling between main and child. So I'd rather not say "go for Example 2".
In your case it rather sounds like child actually is a special case of main, like the relationship between fruit (main) and apple (child). That makes using extends much more reasonable. You seem to be unsure, because you have many child classes extending main. To me this sound just normal, if all the child classes have a similar purpose and share some basic functionalty which is provided by main. But I'm not quite sure what your goal actually is.
Extending classes can break encapsulation, so depending on your classes it might be best to keep your objects separated as in example #2. You could have a loading function to make setting up the main class easier:
class main {
function load($class){
$this->$class = new $class();
}
}
$main = new main();
$main->load('child1');
$main->child1->child_function1();
In php, You have two options. Either (in 2020) inject your Helper Class in another class as suggested in the first answer or in PHP you can use traits.
Traits are similar to classes but their constructors cannot be public.
It's difficult to use Dependency injection on traits but traits can extend existing classes with methods and they can access the parent methods of their respective classes.
With traits anyway you cannot override the parent methods, you can only add the methods to the stack.
Another downside of traits is that, when you use the parent methods of the containing class, type hinting is not well supported in some IDEs. So in order to get type hinting working you'll need some workarounds.
In PHP 5.4.9, the following example triggers the fatal error "B has colliding constructor definitions coming from traits".
trait T {
public function __construct () {
echo __CLASS__ . ": constructor called.\n";
}
}
class A {
use T;
}
class B extends A {
use T;
}
There's no problem when the trait contains a different method than the constructor, and no problem when the constructor is actually copied into the classes (without using traits, the "language-assisted copy & paste" feature).
What's so special about the constructor here? Shouldn't PHP be able to figure out that one of them overrides the other? I couldn't find anything about this limitation in the manual.
This related question mentions a way to get around the problem (by using aliases for trait methods), but not what's causing it in the first place.
Try what happens with the following code:
class A {
use T;
use T;
}
Because this is what you effectively wrote by extending from A and then using T again for B.
If you need to use trait T in base and subclasses, use it only in the base-class.
If you need it in subclasses only, use it only in the leaf subclasses.
I want create a helper class that containing method like cleanArray, split_char, split_word, etc.
The helper class it self will be used with many class. example :
Class A will user Helper, Class B, Class C, D, E also user Helper Class
what the best way to write and use helper class in PHP ?
what i know is basic knowledge of OOP that in every Class that use Helper class must create a helper object.
$helper = new Helper();
It that right or may be some one can give me best way to do that.
I also will create XXX Class that may use Class A, B, C, etc.
UPDATE : ->FIXED my fault in split_word method :D
Based on Saul, Aram Kocharyan and alex answer, i modified my code, but its dont work, i dont know why.
<?php
class Helper {
static function split_word($text) {
$array = mb_split("\s", preg_replace( "/[^\p{L}|\p{Zs}]/u", " ", $text ));
return $this->clean_array($array);
}
static function split_char($text) {
return preg_split('/(?<!^)(?!$)/u', mb_strtolower(preg_replace( "/[^\p{L}]/u", "", $text )));
}
}
?>
and i use in other Class
<?php
include "Helper.php";
class LanguageDetection {
public function detectLanguage($text) {
$arrayOfChar = Helper::split_char($text);
$words = Helper::split_word($text);
return $arrayOfChar;
}
}
$i = new Detection();
print_r($i->detectLanguage("ab cd UEEef する ح خهعغ فق 12 34 ٢ ٣ .,}{ + _"));
?>
Helper classes are usually a sign of lack of knowledge about the Model's problem domain and considered an AntiPattern (or at least a Code Smell) by many. Move methods where they belong, e.g. on the objects on which properties they operate on, instead of collecting remotely related functions in static classes. Use Inheritance for classes that share the same behavior. Use Composition when objects are behaviorally different but need to share some functionality. Or use Traits.
The static Utils class you will often find in PHP is a code smell. People will throw more or less random functions into a class for organizing them. This is fine when you want to do procedural coding with PHP<5.2. As of 5.3 you would group those into a namespace instead. When you want to do OOP, you want to avoid static methods. You want your objects to have High Cohesion and Low Coupling. Static methods achieve the exact opposite. This will also make your code less testable.
Are Helper Classes Evil?
Killing the Helper class, part two
Functional Decomposition AntiPattern
Is the word "Helper" in a class name a code smell?
Moreover, every Class that use Helper class must create a helper object is a code smell. Your collaborators should not create other collaborators. Move creation of complex object graphs into Factories or Builders instead.
As a rule of thumb, helpers should contain functionality that is common but has no special designation under the overall architecture of the application.
Suffix the classname with Helper
Use static methods whenever possible
In short:
// Helper sample
//
class ConversionHelper {
static function helpThis() {
// code
}
static function helpThat() {
// code
}
}
// Usage sample
//
class User {
function createThings() {
$received = ConversionHelper::helpThis();
}
}
Instead of creating static class , you should just write simple functions , and include that file at the index/bootstrap file (you can even use namespaces with it).
Instead of:
class Helper {
static function split_word($text) { ...
static function split_char($text) { ...
}
It should be:
namespace Helper;
function split_word($text) { ...
function split_char($text) { ...
There is no point wrapping it all up in a class. Just because you put it in a class doesn't make it object oriented .. actually it does the exact oposite.
You could create a class with static methods...
class Str {
public static function split_char($str, $chr) {
...
}
}
You could also namespace a bunch of functions with a namespace, but I think the former is preferred.
Use public static methods in the class as such:
/* Common utility functions mainly for formatting, parsing etc. */
class CrayonUtil {
/* Creates an array of integers based on a given range string of format "int - int"
Eg. range_str('2 - 5'); */
public static function range_str($str) {
preg_match('#(\d+)\s*-\s*(\d+)#', $str, $matches);
if (count($matches) == 3) {
return range($matches[1], $matches[2]);
}
return FALSE;
}
// More here ...
}
Then invoke them like this:
CrayonUtil::range_str('5-6');
If in another file, use the following at the top:
require_once 'the_util_file.php';