What is wrong here? Nothing is displayed on the screen - php

nothing is displayed at runtime. xdebug does not run. this simple example doesn't work.
ini_set("display_errors", 1);
error_reporting(E_ALL);
abstract class Hello
{
protected function hello();
}
class Helloworld extends Hello
{
public $world;
public function __construct($world){
$this->world = $world;
}
public function hello() {
echo 'Hello + '.$this->world;
}
}
class Hiotherworld extends Hello
{
public $world;
public function __construct($world){
$this->world = $world;
}
public function hello(){
echo 'Hi + '.$this->world;
}
}
$hello = new Helloworld("Earth");
$hello->hello();
$hi = new Hiotherworld("Mars");
$hi->hello();

Fatal error: Non-abstract method Hello::hello() must contain body:
protected function hello();

You can't change the visibility of a method in a subclass. You declared hello() as protected so it must be protected in sub classes as well.
I guess you wanted to declare it as public in Hello as protected makes no sense in this context. Also you missed the abstract keyword (Thanks #rNix) And you should move the declaration of $world to the base class:
Finally Hello should look like this:
abstract class Hello
{
$protected $world;
abstract public function hello();
}

Change it
abstract class Hello
{
protected function hello(){}
}
working for me.

Related

How to call traits method from the class method that uses that trait if both methods name are same?

trait World {
public function sayHello()
{
echo "World!";
}
}
abstract class AbstractHello{}
class Hello extends AbstractHello {
use World;
public function sayHello()
{
echo "Hello";
$this->sayHello(); // calling its not working
}
}
class Hello2 extends AbstractHello {
use World;
}
Now if I call as follows, it should show "HelloWorld!"
$h = new Hello();
$h->sayHello();
And If call as follows, it should show "World!"
$h = new Hello2();
$h->sayHello();
I do not want to change the traits method name using as operator because sayHello() method has been called from other places for child class like Hello2.
Above code is not working. Any help?
In your Hello class you have to create alias for sayHello() method of trait.
class Hello extends AbstractHello {
use World
{
sayHello as sayHelloWorld;
}
public function sayHello()
{
echo "Hello";
$this->sayHelloWorld(); // calling it's working now
}
}

PHP Trait call inherited function

I have got a trait
trait Foo{
protected static function foo(){
echo 'Hello';
}
}
and a class
class Bar{
use Foo;
private static function foo(){
Foo::foo();
echo ' World!';
}
}
I cannot use Foo:foo(). What can I do to achieve the desired effect?
EDIT
Using
use Foo {foo as parentFoo}
private static function foo(){
self::parentFoo();
echo ' World!';
}
did the trick.
You can do something like this:
class Bar{
use Foo {
Foo::foo as foofoo;
}
private static function foo(){
self::foofoo();
echo ' World!';
}
}
Are you allowed to rename your trait method foo to fooo?
If yes, please do and replace Foo::foo() with Foo:fooo() in your class method body before following static call syntax (by adding static keyword to your trait function definition)
<?php
trait Foo
{
protected static function Fooo()
{
echo 'Hello';
}
}
class Bar
{
use Foo;
private static function foo()
{
self::fooo();
echo ' World!';
}
public static function expose()
{
echo self::foo();
}
}
echo Bar::expose();
EDIT:
Obviously, the answer to my question was "No, you're not allowed to rename the trait method", for which case, you've pointed out a solution related to native conflict resolution embedded in PHP:
http://php.net/manual/en/language.oop5.traits.php#language.oop5.traits.conflict

Class methods in PHP

I am coming from the Ruby world and I have a PHP project I currently work on.
Like in Ruby scripts, is it possible to declare class methods in PHP? Basically, I'm asking what the equivalent of the following code would be in PHP
class A
def hello; "hello from object"; end
def self.hello; "hello from class"; end
end
Note the difference between the instance method and the class method.
In PHP class methods are usually referred to as static methods and are declared as such. To directly translate your example:-
class A
{
public function hello()
{
return "hello from object";
}
//We can't have two methods with the same name.
public static function s_hello()
{
return "hello from class";
}
}
Then you would call the methods like this:-
//For a static method we don't need an instance
echo A::s_hello;
//But we do for an instance method
$a = new A();
echo $a->hello();
You can also have static properties, so the above example could be modified something like this:-
class A
{
private static $s_hello = "hello from class";
private $hello = "hello from object";
public function hello()
{
return $this->hello;
}
//We can't have two methods with the same name.
public static function s_hello()
{
return self::$hello;
}
}
http://php.net/manual/en/language.oop5.static.php
class A
def hello; "hello from object"; end
def self.hello; "hello from class"; end
end
class A {
// attributes or properties
public $age;
private $gender;
protected $location;
// needs to be static to be called as self:: inside the class
public static function hello(){
return "hello from object";
}
// use this keyword to be called inside the class
public function hello1(){
return "hello from object";
}
public function hello2(){
print(self::hello());
print(this->hello1());
}
// How about private method
private function hello3(){
return "hello world";
}
}
Calling Outside the class
$instance = new A();
//static
$instance::hello();
//non static
$instance->hello1();
$instance->hello2();
Look at static methods: http://php.net/static
A static method is called like that:
Foo::aStaticMethod();
There is no way in php to have multiple definition of the same function in single class
rather you can do this
abstract class A{
static function hello()
{
return 'hello';
}
}
class B extends class A
{
function hello()
{
return 'hello from Object';
}
}
A::hello();
$t = new B();
$t->hello();

Edit protected member in php

I have code similar to the following:
class ModuleRaceRegistration extends Module
{
protected $strTemplate = "template";
protected function compile()
{
// this doesn't work
$this->strTemplate = "template2";
}
}
From within the compile function I need to change the $strTemplate member. How can I do this?
Is an error being returned? Also, this might not be the case but compile is a protected method so you can only call it from within the class. If you are trying to call it from outside of the class, then it would need to be public.
Let me try
Example from manual
<?php
abstract class Base {
abstract protected function _test();
}
class Bar extends Base {
protected function _test() { }
public function TestFoo() {
$c = new Foo();
$c->_test();
}
}
class Foo extends Base {
protected function _test() {
echo 'Foo';
}
}
$bar = new Bar();
$bar->TestFoo(); // result: Foo
?>

If i extend a static class in PHP, and the parent class refers to "self::", will this refer to the self in the extended class?

If i extend a static class in PHP, and the parent class refers to "self::", will this refer to the self in the extended class?
So, for example
<?php
Class A
{
static $var
public static function guess(){self::$var = rand(); return $var}
}
Class B extends Class A
{
public static function getVar(){return self::$var}
}
If I ran
B::guess();
then B::getVar();
is the value for Var stored in A::$var or B::$var?
Thank you.
Late static binding was introduced in PHP 5.3, it allows you to control this behavior.
It's easy to test:
class ClassA {
public static function test(){ self::getVar(); }
public static function getVar(){ echo 'A'; }
}
class ClassB extends ClassA {
public static function getVar(){ echo 'B'; }
}
ClassA::test(); // prints 'A'
ClassB::test(); // also prints 'A'
... hope that helps :)
Additional information, usage of self or $this is different into extended classes
class ClassA {
public function test(){ self::getVar(); }
public function test2(){ $this->getVar(); }
public function getVar(){ echo 'A'; }
}
class ClassB extends ClassA {
public function getVar(){ echo 'B'; }
}
$classB = new ClassB();
$classB->test(); // prints 'A'
$classB->test2(); // prints 'B'

Categories