PHP Class Using Same Name as Trait Function - php

I have the following code as a sample.
trait sampletrait{
function hello(){
echo "hello from trait";
}
}
class client{
use sampletrait;
function hello(){
echo "hello from class";
//From within here, how do I call traits hello() function also?
}
}
I could put all the details as to why this is necessary but I want to keep this question simple. Extending from the class client is not the answer here due to my particular situation.
Is it possible to have a trait have the same function name as the class using it, but call the traits function in addition to the classes function?
Currently it will only use the classes function (as it seems to override the traits)

You can do it this way :
class client{
use sampletrait {
hello as protected sampletrait_hello;
}
function hello(){
$this->sampletrait_hello();
echo "hello from class";
}
}
Edit :
Whops, forgot $this-> (thanks JasonBoss)
Edit 2 :
Just did some research on "renaming" trait functions.
If you are renaming a function but not overwriting another one (see the example), both functions will exist (php 7.1.4) :
trait T{
public function f(){
echo "T";
}
}
class C{
use T {
f as public f2;
}
}
$c = new C();
$c->f();
$c->f2();
You can only change the visibility :
trait T{
public function f(){
echo "T";
}
}
class C{
use T {
f as protected;
}
}
$c->f();// Won't work

Yes, You can do it this way also, you can use multiple function of a trait like this.
Try this code snippet here
<?php
ini_set('display_errors', 1);
trait sampletrait
{
function hello()
{
echo "hello from trait";
}
}
class client
{
use sampletrait
{
sampletrait::hello as trait_hello;//alias method
}
function hello()
{
$this->trait_hello();
echo "hello from class";
}
}

Related

How to extend php class to a class which ovverride it's functions

Alright, I have a structure like this:
class Creature{
public function sayHi(){
echo "Hi";
}
}
class HumanType extends Creature(){
}
class Human extends HumanType{
}
class Human232 extends Human{
public function sayHi(){
echo "Hello, bro";
}
}
class Human457 extend Human{
}
$Human = new Human232($id);
echo $Human->sayHi(); //Hello, bro
$Human2 = new Human457($id);
echo $Human2->sayHi(); //Hi
//And then I have this still to be implemented
class HumanCategory576{
public function sayHi(){
echo "Hi from the category!";
}
}
I have of course many classes like:
Human457,
Human458,
Human459,
Human600,
Human601
And also:
HumanCategory576,
HumanCategory577,
HumanCategory578,
HumanCategory579,
HumanCategory580
What I want to do is implement HumanCategory576 in a way that sayHi() would print "Hi from the category!" only if the Human class which is (I suppose) inheriting it is not ovveriding the function, like Human457.
I hope I was clear enough.
How do I do? Thanks
I am assuming that it was your intention for class HumanCategory576 to extend another class.
You can use is_callable() to check if HumanCategory576 parent has the function by:
is_callable('parent::sayHi'){
parent::sayHi();
}else{
echo "Hi from the category!";
}
Please take a is_callable in PHP's documentation.
<?php
class TestClass extends TestClassParent {
/** #brief Object initialisation callback
#returns void */
public function __construct() {
# do initialisation
# ...
# if we have a parent
if(is_callable('parent::__construct')) {
# then bubble up
parent::__construct();
}
}
}
?>

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
}
}

Find out if method was called via trait?

In PHP, how do I find out if a class method was called via a method inherited from a trait?
Say I have a class myClass that uses the Psr\Log\LoggerTrait (see: PSR-3). I need to be able to find out if the method myClass::log() was called via a method from the Psr\Log\LoggerTrait, for example LoggerTrait::debug(), or if it was called directly from outside myClass.
All the methods are non-static.
This is related to a debugging package. I'm not trying to alter behavior based on the caller, I just need to be able to pass that information forward. And to be more precise, I need just the entry point, ie. just the last call outside of my package.
I'm looking at debug_backtrace() but it doesn't seem to offer any direct solutions. Is there some rational way of doing this?
Here's some code:
<?php
class myClass
{
use Psr\Log\LoggerTrait;
public function log($level, $message, array $context = array())
{
if (called_via_trait) {
...
} else {
...
}
}
}
$myObject = new myClass;
$myObject->log('debug', 'This is a direct call');
$myObject->debug('This is a call via a trait method');
You could use get_called_class to determine the class that called it.
trait Test {
public function doTest() {
echo get_called_class() . "\n";
}
}
class Some {
use Test;
public function myFunc() {
$this->doTest();
}
}
$some = new Some();
$some->myFunc(); // Outputs "Some" since Some uses Test
So in your case, inside your class, you could do something like
function test() {
if(get_called_class() == 'myClass') {
// You're in the myClass class
} else {
// You're not in the myClass class
}
}
Yes, you have to use debug_backtrace(); Please follow my example:
namespace Psr\Log;
class LoggerTrait{
public static function debug(){
return myClass::log();
}
}
class myClass{
public static function log(){
$trace = debug_backtrace();
if(isset($trace[1])){
echo'<br />Called by <b>'.$trace[1]['class'].'</b>. ';
} else {
echo'<br />Called by <b>'.$trace[0]['class'].'</b>. ';
}
if(isset($trace[1]['class']) && $trace[1]['class']!=get_class()){
echo'Called outside';
} else {
echo'Called inside';
}
//return get_class();
}
}
trait ExampleTrait {
public function doSay() {
echo LoggerTrait::debug();
echo myClass::log();
}
}
echo LoggerTrait::debug();
echo myClass::log();
echo ExampleTrait::doSay();

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

Can I make a function child of another Class without extends Class?

My Class is independant from another Class.
Inside my Class, a function is doing the same but refined job as a function in another Class. Can I use parent:: function_in_another_class() and get my function join that parent funciton's job flow?
No.
In PHP you can only extend from none or one class. As you write both classes are independent to each other, there is no information where to find the one or the other class.
But what you're looking for is probably this:
class A
{
function myFunction() {}
}
class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
public function myFunction()
{
$this->a->myFunction();
}
}
If any class method already doing the same thing why would you bother call join it?
You can not do it. If you want the same job flow best way to do is to instantiate the other class and invoke that very same method. Thats why we use OOP.
See the example,
interface Fable()
{
public function f();
}
class OtherClass implements Fable
{
public function f()
{
// job flow
}
}
class MyClass
{
private $fable;
public function __construct(Fable $f)
{
$this->fable = $f;
}
public function method1($args){
return $this->fable->f($args);
}
}
If the current class is a child of another class, yes, you can. parent references to the parent class.
From php.net:
<?php
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();
?>
The best you can do here is to extend Class B from Class A
Class B extends Class A
But, you can also:
class ClassA {
function do_something($args) {
// Do something
}
}
class ClassB {
function do_something_inclassA($args) {
classA::do_something($args);
}
}
Important: calling classa::do_something(); is a static call, in other words with error reporting E_STRICT you will get a static notice warning because function do_something() is not static function do_something()
Also, calling this function statically (i.e. classa::do_something()) means that class a's function cannot refer to $this within it

Categories