Calling a function from an extended class - php

I want to develop something like my own framework for further websites, there is an existent answered question about my queries but i would like someone to help me so there is
frameworkclass.php
class Framework{
public function hello(){
echo "Hello World!";
}
anotherclass.php
class New extends Framework{
$hellomessage = self::hello();
}
Well I know that I have to type parent::hello() to call the hello function from Framework class but how can i do it without typing everytime parent::
I don't know maybe something like this $Framework->anyfunction()?
Another thing that I don't understand about oop is whats the difference about a static variable and other types, or between public protected or private functions ?
What is a framework auto load function and whats the difference about the caching system of a framework and a framework based on sessions ?
Thanks!

You can't initialise a property with a method.
class Framework {
public function hello() {
return "Hello World!";
}
}
class New extends Framework {
public $hellomessage;
public function __construct() {
$this->hellomessage = parent::hello();
}
}

Public means the variable or function can be accessed from anywhere outside of the class.
Protected means the variable or function is only available to the class, and its child classes ( the classes that 'extend' it).
Private means the variable or function is only available to the class itself, and not even the child classes that extend it.
I hope this is helpful.

Related

Is there any way to add methods to php classes like in javascript?

I'm writing a plugin for WooCommerce, Today something came across my mind suddenly, I was thinking if there is a way to expend PHP Classes like the way we do that in JavaScript without touching anything in the PHP class( Since WooCommerce will get updated and our changed will be gone ).
I found solutions like using __call method but like i said, the class shouldn't be edited. I want to be able to use something like this WC()->My_custom_method() without touching Woocommerce class.Is it even possible?
For example in JavaScript all we need to do is :
Foo.prototype.bar = function (){
// ...
}
Foo.bar();
PHP does not have prototypical inheritance and classes have no prototype like in JavaScript. You can simulate what you are asking with some hackery, but that will ultimately result in hard to maintain code. So don't go there.
There is a GitHub project at https://github.com/bdelespierre/prototype.php with a Proof of Concept implementation. You might find it interesting to study.
Needless to say, if your aim is just to add some functionality to a class, you can still use PHP's inheritance, e.g. extend the WooCommerce class and add your modifications in the subclass. Then use an instance of that new class instead, e.g.
class MyClass extends SomeWooCommerceClass {
public function bar() {
// your own implementation of bar
}
}
$myObj = new MyClass();
$myObj->bar();
If your aim is to change the behavior of an existing object instance, consider wrapping the instance into a Decorator, e.g.
class WooCommerceDecorator {
private $instance;
public function __construct(SomeWooCommerceClass $instance) {
$this->instance = $instance;
}
public function foo() {
$original = $this->instance->foo();
$original+= 42;
return $original;
}
// … more methods
Then use it by passing the object to the decorator:
$woo = new SomeWooCommerceClass();
$decoratedWoo = new WooCommerceDecorator($woo);
echo $decoratedWoo->foo();
Also see the PHP manual on Inheritance
Your best call would be to use extended class.
class MyClass extends Foo {
public function methodInFoo() {
echo "I Am extended";
parent::methodInFoo();
}
public function additionalFunction() {
echo "I am new method that is not presented in Foo";
}
}
That way you even can have Composer to auto-update core classes and while you are using this extended class, you will have your own functions along with all functionality in core class.
I don't recommend this but you could do something like
class Test {
private $myMethods = array();
public addMethod($name, $func) {
$myMethods[$name] = $func;
}
public callMethod() {
$myMethods[$name]();
}
}
....
$test->addMethod("doSomething", function(){ echo 123;});
$test->callMethod("doSomething");
I didn't test the code it's just an idea

PHP Call Function in a Class - Is there a simpler way?

I am very new to OOP and very rusty on PHP. I was wondering if this is a valid method to call a function from a class?
class newclass {
public function testfunc {
return '1';
}
}
Could I call it like this:
echo testfunc->newclass();
or like this:
echo newclass()::testfunc;
I always see it defined in examples like below and it seemed like extra code?:
$this = new newclass();
$this->testfunc();
echo $this;
Any help would be greatly appreciated as I'm just starting to wrap my head around this OOP thing. If I'm out to lunch maybe someone could suggest a link to a really good guide for a true beginner in classes/OOP. Thanks!
Both ways work and have their use cases.
Your first case is a regular function call using an instance of a class, your second case is a call to a static function.
Static should be used with care and the use of it is very often a sign that refactoring/redesign is necessary.
The point of object oriented programming is to model the world by writing classes (blueprints) and then create as many independent instances of that class with the word new as needed. Each instance is a little organism with the DNA of the class and you can call the same class method on every single instance without influencing the other instances.
A static call however is not related to an instance of a class and therefore there is no object being used. It's a global call of some tool functionality and in fact breaks the idea of encapsulation.
So, I'm not saying there are no use cases for static classes and methods but they should be used with care.
new is the keyword to instantiate the class. If you want to use a method without an instance of the class, it should be a static method. to have a static method, declare the method as static.
class foo
{
public static function bar()
{
return 'hello!';
}
}
How to use it?
echo foo::bar(); //Will print hello
You could make testfunc static and call it like so:
class newclass{
public static function testfunc{
return '1';
}
}
echo newclass::testfunc();
There is nothing like this echo testfunc->newclass(); and doing it like
$class = new newclass();
echo $class->testfunc();
is the proper way to do it when the method is an instance method and not a static one. Note, there is no ability to reference $this within the static method.
You can create a static wrapper for the constructor which would allow for chaining method calls on the same line.
<?php
class ClassA {
static function create() { return new self(); }
function method1() { ... }
}
ClassA::create()->method1();
you can include the php file that contains your functions
<?php
//print.php
function printHello(){
echo "Hello world";
}
?>
then include it and call the function...
<?php
include "print.php";
printHello();
?>

PHP OOP problem

I have classes Video and Audio, which extend class Popular
In class, Video & Audio is a function of "public static function parsing ()" are different in themselves
So, as I can from the class of "Popular" address to the class that calls?
That is in a class of "Popular" is a function of "getSong" which has a function call "parsing ()", but here's how to call this function from the class that turns ..
Hopefully clearly explained ..
Kind of like the opposite function of need "parent"
class Video extends Popular {
public static function parsing()
{
return 'Videooooooooooooo';
.....
}
public static fuinction tratata()
{
....
}
}
class Audio extends Popular {
public static function parsing()
{
.............
return 'Audio';
.....
}
public static fuinction tratata()
{
....
}
}
class Popular {
public static function getSong()
{
$class = '???????';//Video or Audio???
$class::parsing();// ???
}
}
Sorry for bad english.. used google traslate
There is no need for this behavior.
Put the parsing function in the Popular class, so that Audio and Video inherit it. Then your getSong just looks like this.
EDIT: self keyword is bound to the class in which the function is defined. So the below is wrong. The correct answer is to use the static keyword instead - IF you are using PHP 5.3.0 or later.
public static function getSong()
{
static::parsing();
}
below is wrong
public static function getSong()
{
self::parsing();
}
But really, getSong is no longer needed. When a base class implementation is called on a child class, self still refers to the child class, so the correct parsing function will be called automatically.
Did I understand your question correctly?
Also to everyone else: if I'm wrong about this behavior, then shame on me and I need to go back to school. I haven't used this behavior in a while so I may be rusty.
#Tesserex probaly has the best answer.
Not sure whether this is what you mean, but to find out the class name of the current object:
You seem to be using these functions in static context. That makes things more difficult. As far as I know, the only way to find out in that case is PHP 5.3's get_called_class().

How should I make up for the lack of static initializers in PHP?

I'm thinking about putting every class into a separate file and doing the static initialization outside of the class definition.
The problem with this is the fact that the initialization will happen before the said class is actually needed (it will happen when the file which contains the class is included for the first time). It's a problem, because it may happen that the class won't be used at all, hence the initialization is unnecessary. And I think the practice of including the used files not in the beginning of your code is simply a dirty technique.
If anybody has a viable solution to this problem, I would greatly appreciate it.
Take a look at code like this. It uses a singleton instance of the database yet you can still create instances of the class:
class DB
{
private static $_db;
public static function pdo()
{
if (is_null(self::$_db))
{
self::$_db=new PDO('pgsql:host=localhost;
port=5432;
dbname=testdb;
user=postgres;
password=abc123');
self::$_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$_db;
}
public static function factory()
{
return new self;
}
private function __construct() {}
When you want an instance of the DB, you do DB::factory(). DB uses self::pdo() to return the singleton to access the database.
The singleton answer has a problem here... if you use the static methods before an instance of the class is created... then the static initializer has not run... so you might say that one can run the initializer in every static method... that is true but what about just getting and setting static variables... I suppose one could also use __get and __set magic functions for this... there is just a problem with the language in that it does not support static intialization... here is the way it can be done...
in file Hi.php:
class Hi{
public static $v = "0";
}
Hi::$v= "2";
// end of Hi.php file
simple use a .php file per class... and do the static initialization outside of the
class definition...
You might look up for __autoload when a class is not found it is called and supposed to include the file contains that class. You can put static initializers in that function.
Use singleton pattern instead of static calls:
<?php
class Foo {
protected static $_instance;
/**
* #return Foo
*/
public static function getInstance() {
return (null === self::$_instance)?
self::$_instance :
self::$_instance = new Foo();
}
protected function __construct() {
// initialize here
}
}
This is the way I do this. The only cost is testing the $doneinit static member each time you construct.
class Foo {
private static $doneinit=false;
private static init() {
// do static initialisation here
self::$doneinit=true;
}
public function __construct() {
if (!self::$doneinit) self::init();
// go on to do the rest of construction
}
}
Simple, and it keeps everything within the class.

Using $this, self::, parent:: for code readability

I would like to know if it is acceptable/preferred to use self::method() and parent::method() when working in php classes.
You can use $this->method() but $this-> can also refer to a class variable, a parent class variable, or a method from the parent class. There is no ambiguity in self::
Is self:: depreciated and/or are there any caveats or cons to using this style?
I understand that self:: and parent:: refer to a static instance of the class, but in kohana, unless you specifically define a method as static, there does not seem to be a difference.
Thanks.
Added an example:
Assuming this application stores forums from multiple websites...
class Forum_Controller extends Controller {
function __construct()
{
parent::__construct();
}
function index()
{
echo self::categories();
}
/*
* get a list of categories from a specific site.
*/
private function categories()
{
$db = new Database;
$categories = $db->query("
SELECT * FROM
forum_categories
WHERE fk_site = '$this->site_id'
");
$view = new View('categories_view');
$view->categories = $categories;
return $view;
}
}
This examples works in kohana with error reporting set to:
error_reporting(E_ALL & ~E_STRICT);
$this->site_id is defined in the main Controller_Core class (a library in kohana).
As far as I know, $this is not supposed to be available since I am calling self::categories() in a static manner, but it is only when i define categories() as static that it throws an error.
But as I said I much rather prefer using self:: because from a readability perspective, I know exactly where this function should be, rather than using $this which causes ambiguity, to me that is.
There is a difference.
$this refers to an instance of an object.
parent and self are used to call methods statically.
This page of PHP's manual explains it in better detail than I have time to write at the moment. The first example in particular should help to highlight some of the differences. I encourage you to copy paste the first example and mess about with it, as I think its an important concept to get in your mind if you don't already know the difference.
Controllers are not static in Kohana, although they can contain static member variables / methods or constants.
self:: is a shorthand way of writing ClassName:: i.e
class Animal
{
public static $arms = 0;
}
class Dog extends Animal
{
public static $leg = 0;
const NAME = 'dog';
public static function bark()
{
echo 'Woof';
}
}
To call static functions or get constants from a class we use the scope resolution operator ::. Static functions are per class not per object. Saying :: refers to static instances of a class is wrong, it is just a way to access the static methods - there isn't an object instance that has these methods.
so:
Dog::bark(),
Dog::$leg,
Dog::NAME,
we can also use
Animal::$arms
Inside the class Dog we can use self:: and parent:: so that we do not need to type the full class name (as it could be very long!)
In answer to your question though: No - self:: is not deprecated and no it is not bad practice to use it. The reason it is not used in kohana core is for a very different reason.... (transparent class extensions with eval read below for more info...).
p.s calling non-static methods statically is wrong and shouldn't be allowed- if you set error_reporting(E_ALL | E_STRICT) (like you should during development) you will see an error being raised.
Basically what happens is:
Core has a file called:
class Controller_Core {
public function someMethod(){}
}
You create:
// We can use someMethod of Controller_Core
Index_Controller extends Controller {}
This is really extending Controller_Core UNLESS you have created MY_Controller.php which would be class Controller extends Controller_Core.
//MY_Controller.php
class Controller extends Controller_Core
{
// overloads Controller_Core::someMethod without us having to change the core file
public function someMethod(){}
}
I think self:: is used generally for static functions and properties.
I use Kohana, and perhaps the controllers are made static.
I couldn't add a comment (apparently i do not have the required rep!)
class Forum_Controller extends Controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
echo self::categories();
}
/*
* get a list of categories from a specific site.
*/
private static function categories()
{
$db = new Database;
// You cannot use $this in a static function, because static functions are per class
// and not per object it doesnt know what $this is :) (make private static $site_id and use self::$site_id) if this is what you want
$categories = $db->query("
SELECT * FROM
forum_categories
WHERE fk_site = '$this->site_id'
");
$view = new View('categories_view');
$view->categories = $categories;
return $view;
}
}
Like i said, you should use error_reporting(E_ALL | E_STRICT); (change it in the kohana file )
calling private function categories() statically works due to a bug in PHP, you shouldn't be able to do it :)
I strictly use self:: only for static variables and static member function
another thing to note by the way is that this isn't very good MVC design to be making static controller functions that return lists of categories.
Controllers are for dealing with requests, Models are for dealing with data (which is what this is) and Views are for display.
make a model!
class Category_Model extends Model
{
public function categories($site_id)
{
$categories = $this->db->from('forum_categories')->where('fk_site',$site_id)->get();
return new View('categories_view', array('categories' => $categories));
}
}
...
$cat = new Category_Model;
echo $cat->categories(1);

Categories