I have 3 classes..
class 1 :
<?php
include "two.php";
include "three.php";
class One{
public function __construct(){
$two = new Two($this);
$three = new Three($two);
}
}
$api = new One;
?>
class 2 :
<?php
class Two extends AOP {
public function __construct($obj){
//blablabla
}
}
?>
class 3 :
<?php
class Three extends AOP {
public function __construct($obj){
echo get_class($obj);
}
}
?>
But I want the result must output "One".
How to get class name from object inside object?
In your design you have to implement a getter in class two:
class 2 :
class Two
{
private $myObj;
public function __construct($obj)
{
$this->myObj = $obj;
}
public function getMyObj()
{
return $this->myObj;
}
}
then in class 3, you can retrieve class 1:
class Three
{
public function __construct($obj)
{
echo get_class($obj->getMyObj());
}
}
Use the keyword extends to inherit another class. Since PHP does not support multiple inheritances directly. You can get the class that you extend from with parent::$property; or parent::method();. So, you probably want your code to look more like.
// three.php
class Three extends AOP{
public function __construct($obj){
echo get_class($obj);
}
}
// two.php
class Two extends Three{
public function __construct($obj){
parent::__construct($obj); // Constructors do not return a value echo works
}
protected function whatever($string){
return $string;
}
}
// one.php
include 'three.php'; // must be included first for Two to extend from
include 'two.php'
class One extends Two{
public function __construct(){
// change this part
parent::__construct($this); // uses the parent Constructor
echo $this->whatever('. Is this what you mean?'); // call method without same name in this class - from parent
}
}
$api = new One;
I would not use your structure at all, but this should give you an idea of inheritance.
Related
I have large class foo, that I want to split to two separate classes (and files);
My class foo uses contruct function and noumerous $this references.
I need a second class bar to be an extension for original foo class, so I could still use contruction with additional parameter if to include bar class;
$includeBar = true;
$foo = new foo($config, $includeBar);
I've tried putting it this way:
Class bar extends foo {
public function barFunction(){
//some function of bar
}
}
Class foo {
public function __construct($config, $includeBar = true) {
if ($includeBar) {
include_once 'bar.php';
}
}
}
But when I call:
$foo = new foo($config, true);
$foo->barFunction();
It fails, saying
PHP Fatal error: Uncaught Error: Call to undefined method foo::barFunction()
What am I doing wrong? pls help, got stuck
It should be the other way round.
Bar is your base class, that contains all the methods that every sub class also needs. Foo is the extention, the extras, so Foo extends Bar.
<?php
// file bar.php
Class Bar {
public function __construct($config) {
$this->config = $config;
}
public function barFunction() {
echo "I'm everybody ".$this->config['msg'];
}
}
// file foo.php
require_once('bar.php');
Class Foo extends Bar {
public function fooOnly() {
echo "I'm foo ".$this->config['msg'];
}
}
// consuming file index.php
include('foo.php');
$config = array('msg'=>'and I need coffee');
$foo = new foo($config);
$foo->barFunction(); // we can call this, because foo extends bar
// this won't work:
$bar = new Bar($config);
$bar->fooOnly();
// but this:
$bar->barFunction();
$foo->fooOnly();
(all the includes/requires can be omitted when using a proper autoloader!)
If you want reuse class methods or separate class method implementation I think you can use trait and then you can use keyword use to require functions to your class.
For example:
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
?>
The above example will output:
Hello World!
I have a code:
<?php
abstract class Model
{
static protected $_table;
static public function setTable()
{
self::$_table = get_called_class();
}
static public function getTable()
{
if(!isset(self::$_table)) {
self::setTable();
}
return self::$_table;
}
}
class User extends Model {}
class Post extends Model {}
echo User::getTable();
echo "<br>";
echo Post::getTable();
?>
The output of echoing it, is: "User User". I can't understand it why value of property one's class go to another. Why doesn't second echo give 'Post' output? What am I getting wrong?
Because you are using static properties, after Model::$_table gets set the first time your class isn't going to set it again. Unless you change your Model::getTable() function so that it calls self::setTable() every time.
You could also create Model as a trait instead of a traditional class.
For example:
trait class Model
{
static protected $_table;
static public function setTable()
{
self::$_table = get_called_class();
}
static public function getTable()
{
if(!isset(self::$_table)) {
self::setTable();
}
return self::$_table;
}
}
class User {
use Model;
}
class Post {
use Model;
}
echo User::getTable();
echo "<br>";
echo Post::getTable();
Questions says it all really.
I have constants defined in my parent class. I have tried $this->CONSTANT_1 but it's not working.
class MyParentClass
{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass
{
// I want to access CONSTANT_1
}
I think you would need to access it like this:
self::CONSTANT_1;
or alternatively "parent", which will always be the value established in the parent class (i.e., the constant's immutability is maintained):
parent::CONSTANT_1;
Interesting
One thing that is interesting to note is that you can actually override the const value in your child class.
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
const CONSTANT_1=2;
}
echo MyParentClass::CONSTANT_1; // outputs 1
echo MyChildClass::CONSTANT_1; // outputs 2
You can also access to constant define in children from parent method, with the static key.
<?php
class Foo {
public function bar() {
var_dump(static::A);
}
}
class Baz extends Foo {
const A = 'FooBarBaz';
public function __construct() {
$this->bar();
}
}
new Baz;
You do not have to use parent. You can use self which would first check if there is constant with the same name in the class itself, then it would try to access the parents constant.
So self is more versatile and provides the possibility to 'overwrite' the parents constant, without actually overwriting it as you can still explicitly access it via parent::.
Following structure:
<?php
class parentClass {
const MY_CONST = 12;
}
class childClass extends parentClass {
public function getConst() {
return self::MY_CONST;
}
public function getParentConst() {
return parent::MY_CONST;
}
}
class otherChild extends parentClass {
const MY_CONST = 200;
public function getConst() {
return self::MY_CONST;
}
public function getParentConst() {
return parent::MY_CONST;
}
}
Leads to the following results:
$childClass = new childClass();
$otherChild = new otherChild();
echo childClass::MY_CONST; // 12
echo otherChild::MY_CONST; // 200
echo $childClass->getConst(); // 12
echo $otherChild->getConst(); // 200
echo $childClass->getParentConst(); // 12
echo $otherChild->getParentConst(); // 12
<?php
class MyParentClass{
const CONSTANT_1=123;
}
class MyChildClass extends MyParentClass{
public static function x() {
echo parent::CONSTANT_1;
}
}
MyChildClass::x();
Live example: http://codepad.org/Yqgyc6MH
Use parent, for example:
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
function __construct(){
echo parent::CONSTANT_1; //here you get access to CONSTANT_1
}
}
new MyChildClass();
OR:
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
MyParentClass::CONSTANT_1; // here you you get access to CONSTANT_1 too
}
You want to use the self keyword.
class Whale
{
const BLOWHOLES = 1;
}
class BlueWhale extends Whale
{
/**
* A method that does absolutely nothing useful.
*/
public function funnyCalculation()
{
return self::BLOWHOLES + 2; // This is the access you are looking for.
}
}
Check the PHP manual for ways to access class constants inside and outside of the class definition.
I'm wondering how to force sub classes to implement a given interface method.
Let's say I have the following classes :
interface Serializable
{
public function __toString();
}
abstract class Tag // Any HTML or XML tag or whatever like <div>, <p>, <chucknorris>, etc
{
protected $attributes = array();
public function __get($memberName)
{
return $this->attributes[$member];
}
public function __set($memberName, $value)
{
$this->attributes[$memberName] = $value;
}
public function __construct() { }
public function __destruct() { }
}
I would like to force any sub class of "Tag" to implement the "Serializable" interface. For example, if i a "Paragraph" class, it would look this way :
class Paragraph extends Tag implements View
{
public function __toString()
{
print '<p';
foreach($this->attributes as $attribute => $value)
print ' '.$attribute.'="'.$value.'"';
print '>';
// Displaying children if any (not handled in this code sample).
print '</p>';
}
}
How can i force a developer to make his "Paragraph" class implement the methods from the interface "Serializable"?
Thanks for taking the time to read.
Just have the abstract class implement the interface:
interface RequiredInterface
{
public function getName();
}
abstract class BaseClass implements RequiredInterface
{
}
class MyClass extends BaseClass
{
}
Running this code will result in the error:
Fatal error: Class MyClass contains 1 abstract method and must
therefore be declared abstract or implement the remaining methods
(RequiredInterface::getName)
This requires the developer to code the methods of RequiredInterface.
PHP code example:
class Foo {
public function sneeze() { echo 'achoooo'; }
}
abstract class Bar extends Foo {
public abstract function hiccup();
}
class Baz extends Bar {
public function hiccup() { echo 'hiccup!'; }
}
$baz = new Baz();
$baz->sneeze();
$baz->hiccup();
It is possible for an abstract class to extend Serializable, as abstract classes do not need to be base classes
This adds a __constructor to your class Paragraph which checks to see if Serializable is implemented.
class Paragraph extends Tag implements View
{
public function __construct(){
if(!class_implements('Serializable')){
throw new error; // set your error here..
}
}
public function __toString()
{
print '<p';
foreach($this->attributes as $attribute => $value)
print ' '.$attribute.'="'.$value.'"';
print '>';
// Displaying children if any (not handled in this code sample).
print '</p>';
}
}
Why does this abstract class not work and output nothing?
<?php
abstract class Con {
function __construct($name);
}
}
class Shop extends Con {
function __construct($name) {
$this->shopname = $name;
}
function write() {
echo $this->shopname;
}
function outputdate() {
echo ' ' . date('Y');
}
function __destruct() {
$this->outputdate();
}
}
You cannot define some class in other class body. Instead, you must use PHP OOP features to extend one class from another.
class Shop extends Con{
...code goes here....
}
$shop = new Shop('shopname');
$shop->write();
You can't instantiate an abstract class. Also, you can't create a class within another class.
http://php.net/manual/en/language.oop5.abstract.php
http://en.wikipedia.org/wiki/Abstract_type
Check out this link if you are looking to subclass.
http://php.net/manual/en/keyword.extends.php