php extending but with a new constructor...possible? - php

I have a class:
class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
what I would like to do is a have a class that sort of extends the test class. I say 'sort of', because the class needs to be able to run whatever function the test class is able to run, but NOT run the construct unless I ask it to. I do not want to override the construct. Anyone has any idea how to achieve this?

class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
class test_2 extends test {
function __construct() {
if (i want to) {
parent::__construct();
}
}
}

What's wrong with overriding the construct?
class foo extends test {
function __construct() { }
}
$bar = new foo(); // Nothing
$bar->func_one(); // prints 'world'

You could define a "preConstructor" method in your sub-classes that your root-class constructor would execute, and use a boolean flag to determine whether constructor code should be executed.
Like so:
class test
{
protected $executeConstructor;
public function __construct()
{
$this->executeConstructor = true;
if (method_exists($this, "preConstruct"))
{
$this->preConstruct();
}
if ($this->executeConstructor == true)
{
// regular constructor code
}
}
}
public function subTest extends test
{
public function preConstruct()
{
$this->executeConstructor = false;
}
}

Related

use function from index.php like this class->publicF->f()

guys lets say we have this class: all i want to do is to use a specific function to do something, think it as a button, but in a way that you have 1 public function and you can execute parts of it!
CLASS DATA {
public function X() {
function A() {
//do_something
}
}
}
and now i'm in the index.php and i want to call the function A() only.
i tried $data->X()->A() but nothing
i tried $data->X(A()) also nothing
is it possible this?
In the way you've written it, no. Looks to me like you're trying to build something in the way you would a Javascript application. But like Rizier123 points out you could do something like this.
class Foo {
public function getBar(){
return new Bar();
}
}
class Bar {
public function someFunction() {
}
}
$foo = new Foo();
$foo->getBar()->someFunction();
Although I'm not entirely sure why you would want to nest things that way when inheriting would be a better route. Something like this:
class Foo extends Bar {
}
class Bar {
public function someFunction() {
}
}
$foo = new Foo();
$foo->someFunction();
But I guess you could use the former as a way to pass specific constructor parameters in a consistent manor.
class Foo {
public function getRainbow(){
return new Bar('rainbow');
}
}
class Bar {
private $type;
public function __construct($type)
{
$this->type = $type;
}
public function someFunction() {
switch($this->type){
case 'rainbow':
echo 'All the way across the sky.';
break;
default:
echo 'Boring.';
break;
}
}
}
$foo = new Foo();
$foo->getRainbow()->someFunction();

Get name function in PHP

I have some classes:
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc();
}
}
class B
{
public function getNameFnc()
{
echo __METHOD__;
}
}
I'm trying to get the function name of a class B class, but I want the function getNameFnc to return 'demo'. How do I get the name 'demo' in function getNameFnc of class B?
Well, if you really want to do this without passing a parameter*, you may use debug_backtrace():
→ Ideone.com
public function getNameFnc()
{
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
echo $backtrace[1]['function'];
}
* this would be the recommended way although one should never need to know which function has been previously called. If your application relies on that fact, you have got a major design flaw.
You will need to use debug_backtrace to get that information.
I haven't tested the code below but I think this should give you the information you want:
$callers = debug_backtrace();
echo $callers[1]['function'];
Why not pass it?
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc(__METHOD__);
}
}
class B
{
public function getNameFnc($method)
{
echo $method;
}
}
Or use __FUNCTION__ if you don't want the class name.

How to make the inherited class run a method from same class in PHP

Whats wrong with me OOP here.
I want to inherit from Class A
The return_output method will do something common so I don't want to write that in the inherited classes.
However when I do B->return_output() I want it to run the do_something method in Class B, but I see that it always runs the method from Class A.
Should I replace $this with something else?
class A {
private function do_something() {
// do something
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
private function do_something() {
// do something different
}
}
var newClass = new B;
echo B->return_output();
use protected and not private since you are running it inside of scope a and scope b can't access private scope a:
class A {
protected function do_something() {
echo('ado_something');
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
protected function do_something() {
echo('bdo_something');
}
}
$newClass = new B;
echo $newClass->return_output();

Multiple time execution bypass

I have the follow (sample) code:
class Foo {
public function __construct() {
$this->bar = new Bar();
$this->baz = new Bazr();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
$baz = $this->baz->alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo('Hello!');
}
}
new Foo();
Which will generate an Fatal error: Maximum function nesting level of '100' reached, aborting!. What I want is, exactly this, ofcourse with different code and no errors.
What I want is one way to know when my instance is already created and not allow more instances of same object, avoiding circular reference.
Learned about Singletom, but, nothing worked. Have any idea?
The constructor of Foo calls the constructor of Bar which calls the constructor of Foo which calls the constructor of Bar... you get the idea. After 100 times it tells you it's dizzy. Don't create a circular reference like that.
I do not quite understand why you need all this? If only because to get methods of Bar/Baz in class Foo, then you can use:
class Foo {
public function __construct() {
Bar::init();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
}
public function init() {
Baz::alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo 'Hello!';
}
}
new Foo();
Implement dependence Injection is the solution:
class Foo {
public function __construct() {
$this->bar = new Bar(new Baz());
}
}
class Bar {
public function __construct($baz = null) {
$this->baz = $baz;
$this->baz->alert();
}
}
class Baz {
public function __construct() {
}
public function alert() {
echo('Hello!');
}
}
new Foo();

PHP - Automatically call one one before another?

In PHP, is there any way to make class method automatically call some other specified method before the current one? (I'm basically looking to simulate before_filter from Ruby on Rails.
For example, calling function b directly but getting the output 'hello you'.
function a()
{
echo 'hello';
}
function b()
{
echo 'you';
}
Any advice appreciated.
Thanks.
Check this:
class Dispatcher {
/*
* somewhere in your framework you will determine the controller/action from path, right?
*/
protected function getControllerAndActionFromPath($path) {
/*
* path parsing logic ...
*/
if (class_exists($controllerClass)) {
$controller = new $controllerClass(/*...*/);
if (is_callable(array($controller, $actionMethod))) {
$this->beforeFilter($controller);
call_user_func(array($controller, $actionMethod));
/*..
* $this->afterFilter($controller);
* ...*/
}
}
}
protected function beforeFilter($controller) {
foreach ($controller->beforeFilter as $filter) {
if (is_callable(array($controller, $filter))) {
call_user_func(array($controller, $filter));
}
}
}
/*...*/
}
class FilterTestController extends Controller {
protected $beforeFilter = array('a');
function a() {
echo 'hello';
}
function b() {
echo 'you';
}
}
PHP does not support filters.However, you could just modefy your own function to ensure that a() is always run before b().
function a()
{
echo 'hello';
}
function b()
{
a();
echo 'you';
}
Not if you're not willing to override a b() to call both.
You might be interested in AOP for PHP though.
How about this:
function a()
{
echo 'hello';
}
function b()
{
a();
echo 'you';
}
If you are under a class and both functions are in that class:
function a()
{
echo 'hello';
}
function b()
{
$this->a();
echo 'you';
}
Not sure but possibly that's what you are looking for. thanks

Categories