http://hacklang.org/tutorial/ - see last exercise (24).
...
trait T {
require extends C;
...
How would you achive this in PHP?
I'd like to use that in PHP Unit tests, like below:
class EventsTest extends TrafficWebTestCase
{
use EntityRepositoryMock;
use ValidatorMock;
use EventsDataProviderTrait;
An example of trait:
trait ValidatorMock
{
...
protected function getValidatorMock($validateObject, $return = [])
{
if (!method_exists($this, 'getMockForAbstractClass')) {
throw new InvalidTraitUseException();
}
$this->validatorMock = $this->getMockForAbstractClass(
'Symfony\Component\Validator\Validator\ValidatorInterface'
);
$this->validatorMock->expects($this->once())
->method('validate')
->with($this->equalTo($validateObject))
->willReturn($return);
return $this->validatorMock;
}
Those trait create some specific mocks or do other stuff that's only related to a unit test. In those traits I use methods from the \PHPUnit_Framework_TestCase, so I'd like to check if trait is used in a valid context.
I think you want something like that:
trait T
{
public function __construct()
{
if (!($this instanceof C)) {
die('Not an instance of C');
}
echo "Everything fine here<br />";
$this->someMethod();
}
}
class C
{
public function someMethod()
{
echo "required method<br />";
}
}
class A extends C
{
use T;
public function doSomething()
{
}
}
class B
{
use T;
public function doSomething()
{
}
}
$a = new A();
$b = new B();
Using instanceof you can check if object extends some class.
For the following code result will be:
Everything fine here
required method
Not an instance of C
More complex code (without checking in constructor):
trait T
{
public function myFunction()
{
$this->checkHierarchy();
echo "normal actions<br />";
}
public function secondFunction()
{
$this->checkHierarchy('D');
echo "normal actions<br />";
}
private function checkHierarchy($className = 'C')
{
if (!($this instanceof $className)) {
throw new \Exception('Not an instance of ' . $className . "<br />");
}
echo "Everything fine here<br />";
}
}
class C
{
public function someMethod()
{
echo "required method<br />";
}
}
class A extends C
{
use T;
public function doSomething()
{
}
public function __construct()
{
echo "aaa<br />";
}
}
class B
{
use T;
public function doSomething()
{
}
public function __construct()
{
echo "bbb<br />";
}
}
$a = new A();
try {
$a->myFunction();
} catch (\Exception $e) {
echo $e->getMessage();
}
try {
$a->secondFunction();
} catch (\Exception $e) {
echo $e->getMessage();
}
$b = new B();
try {
$b->myFunction();
} catch (\Exception $e) {
echo $e->getMessage();
}
Related
Lets assume I have the following Class method:
public function handleException(fn, args) {
try {
call_user_func_array(fn, args);
} catch (SomeException $e) {
//handle
}
}
function fn1(x, y) {
return $this->handleException(parent::fn1, [x, y]);
}
function fn2(x, y) {
return $this->handleException(parent::fn2, [x, y]);
}
This code does not work.
I was wondering what is the reason for that (Classes no being first Class citizens?)
Use quotes
class A
{
function f1($arg)
{
echo $arg;
}
}
class B extends A
{
function test()
{
call_user_func_array('parent::f1', ['param1']);
}
}
$b = new B();
$b->test();
I have two classes A and B. Class C may be extends A and B. I need to do it optimally.
class A {
public function testA() {
echo "this is function testA \n";
}
}
class B {
public function testB() {
echo "this is function testB \n";
}
}
class C extends A {
public function __call($method, $args){
$this->b =new B();
try {
return !method_exists ($this->b , $method ) || !$this->b->$method($args[0]);
} catch(Exception $e) {
echo "error";
}
}
}
$object = new C();
$object->testA();
$object->testB();
$object->testD();
How I can optimize this code?
Multiple "inheritance" in PHP is handled by Traits, which are available as of 5.4.0
More info here: http://php.net/manual/en/language.oop5.traits.php
trait A {
public function testA() {
echo "this is function testA \n";
}
}
trait B {
public function testB() {
echo "this is function testB \n";
}
}
class C {
use A, B;
public function __call($method, $args){
// Called method does not exists.
}
}
please help me here.
I have a class:
class Foo() {
public function{
if($var = x){
do this;
}
else {
do that;
}
}
}
and another class:
class B extends A() {
public function {
#need to import method from Foo
#to execute on a varible in this class
}
}
Could someone please help me out on how to go about this. The language is PHP
class Foo {
protected $var;
function __construct($var) {
$this->var = $var;
}
function test() {
echo "Method Test from class Foo<br>";
if ($this->var == NULL) {
echo "Test = = Null <br>";
}
else {
echo "Test != = Null <br>";
}
}
}
class Ftt extends Foo {
protected $var1;
function __construct($var, $var1) {
$this->var1 = $var1;
parent::__construct($var);
}
function test() {
parent::test();
echo "Method Test from class Ftt extends Foo";
echo " with $this->var1 <br>";
}
}
$ftt = new Ftt('notnull', 'var1');
$ftt->test('notnull');
$foo = new Foo('');
$foo->test();
class Foo() {
public static function test {
if($var = x) {
do this;
}
else {
do that;
}
}
}
class B extends A() {
private $variable = 2;
public function test {
Foo::test($this->variable);
}
}
I have this scenario:
Interface ClassInterface
{
public function getContext();
}
Class A implements ClassInterface
{
public function getContext()
{
return 'CONTEXTA';
}
//Called in controller class
public function Amethod1()
{
try {
//assuming that Helper is a property of this class
$this->helper->helperMethod($this);
} catch(Exception $ex) {
throw $ex;
}
}
}
Class B implements ClassInterface
{
public function getContext()
{
return 'CONTEXTB';
}
//Called in controller class
public function Bmethod1()
{
try {
//assuming that Helper is a property of this class
$this->helper->helperMethod($this);
} catch(Exception $ex) {
throw $ex;
}
}
}
Class Helper {
public function helperMethod(ClassInterface $interface)
{
try {
$this->verifyContext($interface->getContext());
//dosomething
} catch(\Exception $ex) {
throw $ex;
}
}
private function verifyContext($context) {
if (condition1) {
throw new \UnexpectedValueException('Invalid context.');
}
return true;
}
}
I want my controller class which calls Amethod1 and Bmethod1 to know the type of exception(s) thrown in the process. Is it advisable to rethrow an exception just like it was presented?
Do you think the throw-catch-throw-catch-throw structure reasonable in this case?
Yes, totally reasonable. But: your specific example can be simplified from:
public function Amethod1()
{
try {
//assuming that Helper is a property of this class
$this->helper->helperMethod($this);
} catch(Exception $ex) {
throw $ex;
}
}
To:
public function Amethod1()
{
//assuming that Helper is a property of this class
$this->helper->helperMethod($this);
}
this is my class:
class toyota extends car {
function drive() {
}
function break() {
}
}
class car {
function pre() {
}
}
Is there any way I can do so that when I run $car->drive(), $car->break() (or any other function in toyota), it would call $car->pre() first before calling the functions in toyota?
Yep. You could use protected and some __call magic:
class toyota extends car {
protected function drive() {
echo "drive\n";
}
protected function dobreak() {
echo "break\n";
}
}
class car {
public function __call($name, $args)
{
if (method_exists($this, $name)) {
$this->pre();
return call_user_func_array(array($this, $name), $args);
}
}
function pre() {
echo "pre\n";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
http://ideone.com/SGi1g
You could do the following, but I don't think that is what you want.
class toyota extends car {
function drive() {
$this->pre();
}
function break() {
$this->pre();
}
}
class car {
function pre() {
}
}
You may want to look into PHP specific magic methods. http://php.net/manual/en/language.oop5.magic.php
This will better done with the magic methods called __call()
public function __call($name, $arguments)
{
$this -> pre();
return $this -> $name($arguments);
}
What is this method? It overrides the default method call, so that preCall State can be invoked.
Your toyota class
class toyota extends car {
public function __call($name, $arguments)
{
$this -> pre();
return call_user_func_array(array($this, $name), $arguments);
}
function drive() {
}
function break() {
}
}
If you are using PHP5 (>=5.3.2), there is a solution that works with declaring all methods as private. This will enforce method call from single function call:
exec_method()
To run at: http://ideone.com/cvfCXm
The code snippet is here:
<?php
class car {
//method to get class method
public function get_method($method_name) {
$class = new ReflectionClass(get_class($this));
$method = $class->getMethod($method_name);
$method->setAccessible(true);
return $method;
}
public function exec_method($method_name, $arg_args=array()) {
//execute the pre() function before the specified method
$this->pre();
//execute the specified method
$this->get_method($method_name)->invokeArgs($this, $arg_args);
}
public function pre() {
echo 'pre';
echo '<br />';
}
}
class toyota extends car {
private function drive() {
echo 'drive';
echo '<br />';
}
private function brake() {
echo 'brake';
echo '<br />';
}
}
$toyota = new toyota();
$toyota->exec_method('drive');
$toyota->exec_method('brake');
?>
Reference:
Answer to Best practices to test protected methods with PHPUnit [closed]
Just add a constructor, like this...
class toyota extends car {
function __construct() {
$this->pre();
}
function drive() {
echo "drive!";
}
function dobreak() {
echo "break!";
}
}
class car {
function pre() {
echo "Hello!";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
Classes which have a constructor method call this method on each
newly-created object, so it is suitable for any initialization that
the object may need before it is used.
break is reserved, so you shouldn't use this as a function name.