I have been trying to figure out how to go about doing this but I am not quite sure how.
Here is an example of what I am trying to do:
class test {
public newTest(){
function bigTest(){
//Big Test Here
}
function smallTest(){
//Small Test Here
}
}
public scoreTest(){
//Scoring code here;
}
}
Here is the part I am having problems with, how do I call bigTest()?
Try this one:
class test {
public function newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public function scoreTest(){
//Scoring code here;
}
}
$testObject = new test();
$testObject->newTest();
$testObject->scoreTest();
The sample you provided is not valid PHP and has a few issues:
public scoreTest() {
...
}
is not a proper function declaration -- you need to declare functions with the 'function' keyword.
The syntax should rather be:
public function scoreTest() {
...
}
Second, wrapping the bigTest() and smallTest() functions in public function() {} does not make them private — you should use the private keyword on both of these individually:
class test () {
public function newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public function scoreTest(){
//Scoring code here;
}
}
Also, it is convention to capitalize class names in class declarations ('Test').
Hope that helps.
class test {
public newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public scoreTest(){
//Scoring code here;
}
}
I think you are searching for something like this one.
class test {
private $str = NULL;
public function newTest(){
$this->str .= 'function "newTest" called, ';
return $this;
}
public function bigTest(){
return $this->str . ' function "bigTest" called,';
}
public function smallTest(){
return $this->str . ' function "smallTest" called,';
}
public function scoreTest(){
return $this->str . ' function "scoreTest" called,';
}
}
$test = new test;
echo $test->newTest()->bigTest();
To call any method of an object instantiated from a class (with statement new), you need to "point" to it. From the outside you just use the resource created by the new statement.
Inside any object PHP created by new, saves the same resource into the $this variable.
So, inside a class you MUST point to the method by $this.
In your class, to call smallTest from inside the class, you must tell PHP which of all the objects created by the new statement you want to execute, just write:
$this->smallTest();
In order to have a "function within a function", if I understand what you're asking, you need PHP 5.3, where you can take advantage of the new Closure feature.
So you could have:
public function newTest() {
$bigTest = function() {
//Big Test Here
}
}
class sampleClass
{
public function f1()
{
return "f1 run";
}
public function f2()
{
echo ("f2 run" );
$result = $this->f1();
echo ($result);
}
f2();
}
output :
f2 run
f1 run
You need to call newTest to make the functions declared inside that method “visible” (see Functions within functions). But that are then just normal functions and no methods.
example 1
class TestClass{
public function __call($name,$arg){
call_user_func($name,$arg);
}
}
class test {
public function newTest(){
function bigTest(){
echo 'Big Test Here';
}
function smallTest(){
echo 'Small Test Here';
}
$obj=new TestClass;
return $obj;
}
}
$rentry=new test;
$rentry->newTest()->bigTest();
example2
class test {
public function newTest($method_name){
function bigTest(){
echo 'Big Test Here';
}
function smallTest(){
echo 'Small Test Here';
}
if(function_exists( $method_name)){
call_user_func($method_name);
}
else{
echo 'method not exists';
}
}
}
$obj=new test;
$obj->newTest('bigTest')
You can also use self::CONST instead of $this->CONST if you want to call a static variable or function of the current class.
Related
Could someone help me understand how I can make functions within class methods, that would allow me to do things like this:
$class->send->activation_email()
I've seen many APIs do this, so I've tried:
class MyClass
{
public function send()
{
function activation_email()
{
echo "success!";
}
}
}
Undefined property: MyClass::$send
Consider:
class emailSender()
{
function activation_email()
{
if (mail($this->to, $this->subj, $this->body)) {
print $this->msg;
}
}
class MyClass
{
var $send;
function __construct()
{
$this->send=new emailSender();
$this->send->msg="success!";
}
}
$obj=new MyClass();
$obj->send->activation_email();
You probably want to an instance of another class within your class. Make a variable inside your class like this:
$this->otherclass = new Otherclass();
In this case, you can call functions from your other class the following way:
$myClass->otherclass->otherClassFunction()
Someone had answered but deleted the post. This is along the lines of what I was hoping for, and it works as expected:
class MyClass {
public function send(){
echo "Sending: ";
return $this;
}
public function activation_email(){
echo "activation email.";
}
}
$myClass = new MyClass();
$myClass->send()->activation_email();
What you are referring to (shame on no one for noticing this, for shame) is called "method chaining". A lot of big frameworks do this. Consider this example of use:
echo $obj->setName('Mike')->convertMtoN()->getName();
// Echoes "Nike"
Cool.
But here is how it works:
class Example {
private $name = '';
public function setName($name) {
$this->name = $name;
// We return the object, so you can call it again.
return $this;
}
public function convertMtoN() {
// Let's do Caps first
$this->name = str_replace("M", "N", $this->name);
// Then lowercase
$this->name = str_replace("m", "n", $this->name);
// We return the object, keep working
return $this;
}
public function getName() {
return $this->name;
}
}
$name = new Example;
echo $name->setName('Mike')->convertMtoN()->getName();
Essentially, for each method that does not implicitly return a value, you simply return the object, allowing you to continue chaining.
Awesome, right?
PHP rocks (now, I know it has its faults, but with HHVM and process forking, it basically rocks [dude, you will get there]).
You can play with this here:
https://ideone.com/fMcQ9u
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.
Is there a way to call an inherited method, without specifying it's function name?
Something like:
class Child extends Parent {
function some_function(){
// magically inherit without naming the parent function
// it will call parent::some_function()
parent::inherit();
// other code
}
function another_function(){
// it will call parent::another_function()
$result = parent::inherit();
// other code
return $result;
}
}
I could think of a hack to do this using debug_backtrace(), get the last function where inherit() was called and access it's parent with the same function name. I was wondering if there's a nicer way instead of using debug functions which are clearly not meant for this.
You can use the magic __FUNCTION__ constant.
class A
{
function some_function()
{
echo 'called ' . __METHOD__;
}
}
class B extends A
{
function some_function()
{
call_user_func(array('parent', __FUNCTION__));
}
}
$b = new B;
$b->some_function(); // prints "called A::some_function"
Instead of
call_user_func(array('parent', __FUNCTION__));
you can also do
parent::{__FUNCTION__}();
Dirty, but:
class Adult {
function mummy(){
return 'Walk like an Egyptian';
}
function daddy(){
return 'Luke, I am your father';
}
}
class Child extends Adult {
function mummy(){
echo 'Mummy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
function daddy(){
echo 'Daddy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
}
$o = new Child();
$o->mummy();
$o->daddy();
EDIT
Actually giving you a parent method called inherit();
class Adult {
private function mummy(){
return 'Walk like an Egyptian';
}
private function daddy(){
return 'Luke, I am your father';
}
protected function inherit($method) {
$beneficiary = explode('::', $method)[1];
return $this->$beneficiary();
}
}
class Child extends Adult {
public function mummy() {
echo 'Mummy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
public function daddy() {
echo 'Daddy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
}
$o = new Child();
$o->mummy();
$o->daddy();
Dynamically calling functions:
static::$functionName();
In your case:
$func = __FUNCTION__;
parent::$func();
Note: the function name must be a string, if it's the actual function (not really relevant in this context) then it first needs to be converted to its string name first.
Other stuff that your question will probably lead you towards in the long run.
Check out late static binding it's what you're looking for.
Example taken from the linked page.
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
i have seen in some libraries something like this :
$this->getResponse()->setRedirect($returnUrl);
How is this 'multicall' done, or, how should the class be build to do something like this?
I think :
class greeting
{
public function hi()
{
public function howAreYou()
{
echo 'How are you?';
}
}
}
$greet = new greeting;
$greet->hi()->howAreYou();
But i think it's not so good, i would better use something like extends, but i don't know. Thx for your suggestions.
If this is a class instance calling itself, it is called "method chaining".
In PHP, can be done by using return $this; note that this is a very different mechanism than class inheritance - it doesn't really make sense to treat them as interchangeable.
See also: https://stackoverflow.com/search?q=method+chaining+php
getResponse() is returning a class instance which has a setRedirect() method.
Example:
class Foo
{
public function getResponse()
{
$redirect = new Bar();
return $redirect;
}
}
class Bar
{
public function setRedirect($returnUrl)
{
// do something
}
}
$foo = new Foo();
$foo->getResponse()->setRedirect("returnUrl");
No.
All you have to do is return self at very end of each function.
So Your example would be like>
class greeting
{
public function hi()
{
echo "Hi";
return $this;
}
public function howAreYou()
{
echo 'How are you?';
return $this;
}
}
$greet = new greeting;
$greet->hi()->howAreYou();
Or even:
$greet->hi()->howAreYou()->hi()->howAreYou();
class stutter{
public function a(){
echo 'h';
return $this;
}
public function b(){
echo 'hello world!';
}
}
$var=new stutter();
var->a()->b();
Output is:
h hello world
Chaining methods is not the same as declaring functions within a method... in fact the latter will spit an error (not the function declaration, but the way you're calling it). In order to chain a method, just have it return the object itself:
Class chainableObject
{
public $name=null;
public function __construct($name='')
{
$this->name=$name;
return $this;
}
public function setName($name)
{
$this->name = $name;
return $this;//makes chainable
}
public function greet()
{
echo 'Hello, '.$this->name;
return $this;
}
}
$chain = new chainableObject('Frank')->greet();//outputs: Hello, frank
The explanation: All methods return the instance itself, so basically, read the last line of the snippet like this [create object with name:Frank]=>call method greet on the return value of this action. Since the return value is $this, the object that has a greet method, that's what will happen... easy, for more info: just google php method chaining
I'd like to start by showing a test case:
class A {
public static $instance=null;
public function __construct(){
self::$instance=$this;
}
public function className(){
return get_class(self::$instance);
}
}
class B extends A {
public function className(){
return get_class(self::$instance);
}
}
// test code
$b=new B();
echo $b->className; // B
$a=new A();
echo $a->className; // A
echo $b->className; // A <- error: not B any more!
Notes
I'm using a factory+singleton patterns above. Well, somewhat.
I don't need any specs on "implementing patterns correctly". I need problem solving, not KISS violations ;).
Critics might say A should be an interface. Ideally, that's what it should have been, but it's just a simple class, sorry.
The issues lies in the fact that self::$instance is the same for all instances. How do I separate self::$instance for each class?
Edit: I've had this idea:
$GLOBALS['store']=array();
class A {
public static $instance=null;
public function __construct(){
$GLOBALS['store'][__CLASS__]=$this;
}
}
You could store an instance per class name:
class A {
public static function getInstance(){
// Maybe use this function to implement the singleton pattern ...
return self::$instance[get_called_class()];
}
public function className(){
return get_class(self::getInstance());
}
}
You can not do this the clean way.
That is one of the mayor drawbacks on stati propertys: you cannot overrride them.
But you wantet an sollution so.....here is the worarround:
use __calllStatic
<?php
class A {
public static function __callstatic($name,$args)
{
if($name="getClass"){
return 'A';
}
}
}
class B extends A{
public static function __callstatic($name,$args)
{
if($name="getClass"){
return 'B';
}
}
}
echo A::getClass();
echo B::getClass();
?>
the output of this is "AB";
You can add a public static $instance=null; declaration in class B.
class A {
public static $instance=null;
public function __construct(){
self::$instance=$this;
}
public function className(){
return get_class(self::$instance);
}
}
class B extends A {
public static $instance=null;
public function className(){
return get_class(self::$instance);
}
}
// test code
$b=new B();
echo $b->className(); // B
$a=new A();
echo $a->className(); // A
echo $b->className(); // Now returns B, as desired.