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().
Related
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.
I recently began to develop in php5 in an object oriented way and I'm stuck at something. I would really appreciate your help/recommendations.
Bear with me in this since it ended up in a mess :-(
This is my scenario (hope I can elaborate on this clearly): I have two dynamic classes, Client and Supplier which use methods of a static class called Vocabulary. Vocabulary is a class that pulls vocabulary terms from a source which can be: plain text file, mongodb database or mysql database. An entry in a configuration file determines which of the
aforementioned three types of sources the application will use.
class Client {
public function foo() {
...
Vocabulary::getTerm();
...
}
...
}
class Supplier {
public function bar() {
...
Vocabulary::getTerm();
...
}
...
}
class Vocabulary {
public static function useVocab($vocab) {
$_SESSION['vocab'] = $vocab;
}
public static function getTerm($termKey) {...}
...
}
I planned to create Vocabulary child classes for each of the types I want to support, for example: Vocabulary_file, Vocabulary_mongodb and Vocabulary_mysql.
Vocabulary_file will override its parent useVocab() because it needs to perform additional operations appart from setting the $_SESSION variable, but
Vocabulary_mongodb and Vocabulary_mysql don't need to override their useVocab() parent method (they just need the $_SESSION variable set).
All three Vocabulary "child" classes will override getTerm() method.
The following is what I tried and this is the mess I ended up with :-(
For Vocabulary_mongodb and Vocabulary_mysql, since useVocab() doesn't exist but is inherited from Vocabulary, "method_exists()" returns true and that call
causes an infinite loop.
I looks weird both calling the child explicitly in Vocabulary and calling the parent:: in the child class.
After lots of cups of coffee I have exhausted all my wits and my brain is damaged.
// Class Vocabulary modified to make it call the desired "child" class too
class Vocabulary {
// This would execute "child" class method
private static function _callChild($method, $args) {
$child_class = 'Vocabulary_' . Config::$vocab['type']; // Config::$vocab['type'] can be: file, mongodb or mysql
if (method_exists($child_class, $method)) {
return call_user_func_array($child_class . '::' . $method, $args);
} else {
return false;
}
}
public static function useVocab($vocab) {
$_SESSION['vocab'] = $vocab;
self::_callChild(__FUNCTION__, compact('vocab'));
}
public static function getTerm($termKey) {
$termKey = strtolower($termKey);
self::_callChild(__FUNCTION__, compact('termKey'));
}
...
}
class Vocabulary_file extends Vocabulary {
public static function useVocab($vocab) {
parent::useVocab($vocab);
// some specific stuff here
}
public static function getTerm($termKey) {
parent::getTerm($termKey);
// some specific stuff here
}
}
class Vocabulary_mongodb extends Vocabulary {
public static function getTerm($termKey) {
parent::getTerm($termKey);
// some specific stuff here
}
}
class Vocabulary_mysql extends Vocabulary {
public static function getTerm($termKey) {
parent::getTerm($termKey);
// some specific stuff here
}
}
I would like to know how can I design the Vocabulary classes in order to keep the Vocabulary::... like calls in Client and Supplier and let Vocabulary know which child class use for the type configured in "Config" class.
Any advice will be greatly appreciated.
Cheers
If you're using all static methods, you may as well not use OOP at all, it's basically all just global function calls. If you want inheritance with polymorphism to work, you pretty much need to instantiate your classes. The polymorphism then comes from the fact that the instantiated objects can be anything, but you're calling the same methods on them. E.g.:
abstract class Vocabulary {
abstract public function getTerm($termKey);
}
class Vocabulary_File extends Vocabulary {
public function getTerm($termKey) {
// get from file
}
}
class Vocabulary_MySQL extends Vocabulary {
public function getTerm($termKey) {
// get from database
}
}
You can use this polymorphic like this:
if (mt_rand(0, 1)) {
$vocab = new Vocabulary_File;
} else {
$vocab = new Vocabulary_MySQL;
}
// This call is polymorphic.
// What exactly it does depends on which class was instantiated.
$vocab->getTerm('foo');
This is how polymorphism is really useful. The interface (getTerm($termKey)) is defined and unchanging between classes, but the specific implementation changes. If your code is hardcoding calls to Vocabulary::getTerm(), that's not polymorphism. With your structure you're also violating an important OO design rule: The parent does not know about its children, and it does not interact with its children. The children override functionality of the parent, not the other way around.
You also shouldn't use the $_SESSION as a form of global storage. Keep objects self contained.
The keyword self suffers from inability to handle 'late-static-binding'. Basically, in the parent class, self thinks it's the parent class when it's inside it's own static functions (since self is still evaluated at compile time for legacy reasons).
You need to use static instead of self in the parent class (assuming you have php 5.3 or higher).
BTW: the parent keyword functions as you'd expect as the parent has to be known at compile time anyhow.
Here's an example:
public static function getTerm($termKey) {
$termKey = strtolower($termKey);
static::_callChild(__FUNCTION__, compact('termKey'));
}
If you're using php 5.2 and earlier, you have to try a hack around, like require all child classes to have static functions that return their class name. I hope you're on php 5.3 or higher...
Is there any possibility to reduce the access level of a function in a derived class in PHP?
example (... means more code)
class foo
{
public function myFunction() { ... }
public function myOtherFunction() { ... }
}
class bar extends foo
{
private function myFunction() { ... }
}
Now I should'nt be able to call MyFunc ion a bar object. But doing it this way doesn't seem to be valid in PHP. Any other way? I know I could implement an empty function but I don't want to expose the function in the interface at all.
Its not valid in OOP anyway. If you implement a public method, you promise, that this class and all children provides this functionality. To remove a public method means, that you break your promises ;) Because all public methods and properties define the interface of the class and breaking an interface is never a good idea.
Without any clearer information about what you are going to do I suggest to just throw an exception, something like "Not supported".
Let's have this class
class A {
protected static function ident() { return "I am A"; }
public static function say() { return "I say '".self::ident()."'!"; }
}
Then I need to extend class A and override the ident() like this
class B extends A {
protected static function ident() { return "I am B"; }
}
Now when B::say(); is called, the result is I say 'I am A'. Is there any technique how to force it to produce I say 'I am B' without overriding the say() method? (Please don't ask me why to do this, just trust me it is reasonable in my project)
I believe it is possible via abstract class or interface, but I can not figure out how. If it is impossible in PHP, is there any language (except Haskell) which implements this feature?
Since PHP 5.3 late static bindings are available. You shouled take a look at that.
http://php.net/manual/en/language.oop5.late-static-bindings.php
say() is a static method, this kind of method belong to the class, not to an instance, it's not really inherited. If you want to create your own method you have to "override it" (but again it's not overriding).
I'm a big fan of OOP in php, but i feel like defining class methods gets disorganized so fast. I have a pretty good background in OOP in C++, and i am pretty comfortable with how it is handled there, and am curious if there are ways to do it similarly in php.
To be more specific, here is what i mean. I like how in C++ you can define a class header (myclass.h) and then define the actual details of the functions in the implementation file (myclass.cc). Ive found that this can easily be replicated using interfaces in php, but i havent found a good solution for the following:
I like to organize my code in C++ in different files based on how they are accessed, so for example, public methods that can be called outside of the class would be in 1 place, and private methods would be organized somewhere else - this is personal preference.
Ive tried to define class methods in php like:
private function MyPHPClass::myFunction(){ }
when the definition isnt directly inside the class block( { } ), but i havent had any success doing this.
Ive been through all of the pages on php.net, but couldnt find anything like this. Im assuming that there is no support for something like this, but thought i would ask anyway.
thanks
You can't do this. The class declarations are Java-like.
You have to put everything in one file or, at minimum, have some helper classes -- be they only static methods to which you forward or calls or with you deferring some implementation to encapsulated objects. You can also use the __call and __callstatic magic methods to reduce the size of your stubs, but that only works for public methods and I would recommend that you avoid magic methods.
EDI2: As RobertPitt pointed in a comment, you should consider alternative strategies that divide the functionality between several classes. It has the added advantage that it can make your code more decoupled. If you need, you can still unify the functionality of the several classes behind a façade.
EDIT: By using magic methods, I mean something like this:
class MyClassHelper {
public function method_one(array $args) {
...
}
public function method_two(array $args) {
...
}
}
class MyClass {
/**
* #var MyClassHelper
*/
private $helper;
private static $ALLOWED_METHODS = array("method_one" => NULL,
"method_two" => NULL);
public function __call($name, $arguments) {
$name = strtolower($name);
if (array_key_exists($name, self::$ALLOWED_METHODS) {
$helper->$name($arguments);
}
else
throw new Exception(...);
}
}
I should recommend that you avoid this, there are many pitfalls to this (handling of references, no code completion).
Im not really a C++ / C# Programmer but interfaces in php i can give you an exampe to see if this helps.
Interface
interface IDatabase
{
public function connect($dns = '');
public function disconnect($flushCache = false); //Do not use braces, Code free in interfaces
}
Database abstract base class
abstract class Database
{
//Some driver logic here to laod mysql,oracle etc
}
MySql Driver
class DBDriver_MySQl extends Database implements IDatabase
{
public function connect($dns = '')
{
//Connection logic.
}
public function disconnect($flushDns)
{
//Disconnect Login
}
}
Hope this is what your looking for.