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();
Related
How can I create something like
MyObject->property->method()
in PHP?
I only know how to create a method for a class:
class MyObject
{
public function MyMethod()
{
// do something
}
}
In Javascript I can easily do something like
var MyObject = {
property : {
method : function ()
{
// do something
}
}
}
How do I do that?
In Javascript you can create objects and methods inline, in PHP you need to have a class and instantiate it:
class Foo {
public function method() {}
}
class MyObject {
public $property;
public function __construct() {
$this->property = new Foo;
}
}
$o = new MyObject;
$o->property->method();
You can set an object as the value of a property. Something like this:
class Foo {
public $Bar;
public function __construct() {
$this->Bar = new Bar();
}
}
class Bar {
public function ShowBar() {
echo 'Bar';
}
}
$Foo = new Foo();
$Foor->Bar->ShowBar();
As others have correctly answered, this works differently in PHP and Javascript. And these differences are also the reason why in PHP you need to define the class methods before you run them. It might become a bit more dynamic in the future but I'm sure not on the level of Javascript.
You can however fake this a bit in PHP because you can assign functions to properties dynamically:
$myObject = new PropCall;
$myObject->property->method = function() {
echo "hello world\n";
};
$myObject->property->method();
This example outputs:
hello world
This does work because some little magic has been added in the instantiated object:
class PropCall
{
public function __call($name, $args) {
if (!isset($this->$name)) {
return null; // or error handle
}
return call_user_func_array($this->$name, $args);
}
public function __get($name) {
$this->$name = new PropCall;
return $this->$name;
}
}
This class code checks if a dynamic property has been added with the name of the method called - and then just calls the property as a function.
I am trying to access the results of a function that is public inside another class, but I'm not entirely sure how to do this. The class i'm trying to access require parameters, so the class_name::function() method is not working. I'm still new to working with classes, and trying to learn it.
Class one:
class foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
echo $this->var1;
}
}
Class 2
class bar {
public function secondFunc() {
var_dump(**RESULT FROM foo->myFunc HERE);
}
}
These two classes are a basic example of what i'm actually doing, but from this you should get the general idea of my question.
For the correct result to display, the first class needs the params passed to it otherwise the function fails.
I tried using foo::bar(), but this doesn't pass any params to the first class, and it therefor fails.
So, how do I access myFunc from foo inside secondFunc from bar?
You have to pass an instance of foo to bar:
class Foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
return $this->var1;
}
}
class Bar {
private $foo;
function __construct(Foo $foo) {
$this->foo = $foo
}
public function secondFunc() {
var_dump($this->foo->myFunc());
}
}
$bar = new Bar(new Foo('something'));
$bar->secondFunc();
Is that what you want?
Your example isn't very practical but here is the basic idea
public function secondFunc($dependency) {
var_dump($dependency->myFunc());
}
or...
public function secondfunc() {
$foo = new foo();
var_dump($foo->myFunc();
}
What about
class bar {
public function secondFunc() {
$foo = new foo($param);
var_dump($foo->myFunc());
}
}
Or do you need something in one line?
Is it possible to create a function out of a class method?
ie.
class Test {
public function __construct()
{
if ( ! function_exists('foo') ) {
function foo ()
{
return $this->foo();
}
}
}
private function foo()
{
return 'bar';
}
}
Or would I have to do it the other way around, creating a function and using it within the method?
Just do it like that, php is able to do it
class Test {
public function __construct()
{
if ( ! function_exists('foo') ) {
function foo ()
{
return $this->foo();
}
}
}
private function foo()
{
outsidefunction();
return 'bar';
}
}
private function outsidefunction()
{
return 0;
}
i'm trying to create a global function that is a copy of the class method. I come from javascript land where functions are just variables and you can easily copy them...
Functions in PHP are not first class citizens, you cannot copy functions around like variables in PHP. You can hand a reference to a function around, but not the function itself.
In theory, you could use Reflection to get a Closure, reference it via $GLOBALS and then define a function foo to call the Closure from $GLOBALS, e.g.
<?php // requires 5.4
class Test {
public function __construct()
{
if (!function_exists('foo')) {
$reflector = new ReflectionMethod(__CLASS__, 'foo');
$GLOBALS['foo'] = $reflector->getClosure($this);
function foo() {
return call_user_func($GLOBALS['foo']);
}
}
}
private function foo()
{
return 'bar';
}
}
$test = new Test();
echo foo();
Run Demo
However, that is extremely ugly and you do not want to do it this way.
If you want more JavaScript like objects, have a look at
http://www.phpied.com/javascript-style-object-literals-in-php
But still, even the suggested techniques in there are kludges imo.
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
Please take a look at this code:
class Foo {
public $barInstance;
public function test() {
$this->barInstance = new Bar();
$this->barInstance->fooInstance = $this;
$this->barInstance->doSomethingWithFoo();
}
}
class Bar {
public $fooInstance;
public function doSomethingWithFoo() {
$this->fooInstance->something();
}
}
$foo = new Foo();
$foo->test();
Question: is it possible to let the "$barInstance" know from which class it was created (or called) without having the following string: "$this->barInstance->fooInstance = $this;"
In theory, you might be able to do it with debug_backtrace(), which as objects in the stack trace, but you better not do it, it's not good coding.
I think the best way for you would be to pass the parent object in Bar's ctor:
class Foo {
public $barInstance;
public function test() {
$this->barInstance = new Bar($this);
$this->barInstance->doSomethingWithFoo();
}
}
class Bar {
protected $fooInstance;
public function __construct(Foo $parent) {
$this->fooInstance = $parent;
}
public function doSomethingWithFoo() {
$this->fooInstance->something();
}
}
This limits the argument to being proper type (Foo), remove the type if it's not what you want. Passing it in the ctor would ensure Bar is never in the state when doSomethingWithFoo() would fail.