Suppose I have the following code:
class siteMS
{
...
function __CONSTRUCT()
{
require 'config.php';
$this->config = new siteMSConfig;
...
}
...
}
From inside the siteMSConfig class can I determine weather or not it is being called from inside the siteMS class?
Yes, but there's no "pretty" way to do it - you'll end up looking through a backtrace or something similar.
It would be better to pass an (optional?) parameter to the siteMSConfig constructor like this:
class siteMSConfig
{
public function __construct($inSiteMS = false)
{
}
}
or alternatively, subclass siteMSConfig:
class siteMSsiteMSConfig extends siteMSConfig
{
public function __construct()
{
// Possibly call parent::__construct();
}
}
Technically yes, you could use debug_backtrace to figure out who your caller was.
Writing a class which alters its behaviour based purely on where it called from is asking for a world of pain later on though. Why not parameterise the different behaviour, or make a subclass?
I guess you have to pass it with variable, from what place you called it
$this->config = new siteMSConfig ('siteMS');
Related
I wonder if I can make controllers implementing some methods no matters if that method will be public, private or protected and if it will have any parameter. I just want to ensure, that controller has method with specified name, no more.
For example:
interface SomeInterface {
function someFunction();
function someOtherFunction();
}
class SomeController extends SomeBaseController implements SomeInterface {
//some action
public function someAction() { ... }
//an implementation of SomeInterface method
public function someFunction() { ... }
//an implementation of SomeInterface method
protected function someOtherFunction($someParameter) { ... }
}
I know that it's not possible to do this with ordinary php interfaces but maybe there is some other way in php or maybe symfony2 has some tool to accomplish this?
I know of one way to do this, which relies on the __call() method available in PHP: http://www.php.net/manual/en/language.oop5.overloading.php#object.call
__call() is triggered when invoking inaccessible methods in an object context.
You could go ahead and create a parent class that looks like this - although it's not an Interface, so take care if you need it outside a single domain.
class BaseClass{
public function __call($name, $arguments) {
$methodsToImplement = array(
'method1', 'method2', 'method3'
);
if (in_array($name, $methodsToImplement)) {
throw new Exception("Method " . $name . " is not yet implemented.");
}
}
}
It seems there is no way to accomplish this. So I mark my question as reslolved, however if someone knows an answer let me know! :)
I want to be able to create methods within __construct
I tried using lambda in the following way
// This is what I am trying to achieve as an end result
class A extends Z{
public function __construct() {
parent::__construct()
}
public function myfunc() { // do something }
}
// This was an attempt to implement it
class A extends Z{
public function __construct() {
//example
if ($something_is_true) {
$this->myfunc = function () {}
}
parent::__construct()
}
}
I hope this explains what I am trying to achieve
EDIT
I have URLs mapped to functions, and I want to have some logic to determine what URL-mapped-functions exist on the class
Don't think that's possible. But another way to dynamically 'create' methods within a class is to use the magic __call() method.
With this method implemented, any attempt to call a non-existent method on an object will call the __call() method instead. The first parameter passed in will be the name of the function that the user called, and the second parameter will be the arguments.
See the manual for further details.
Once a class has been defined, you can't add new methods to it using standard PHP. I'd advise using __call as well but you can also accomplish what you want, if you're ok with using variable variables, by creating the function contents dynamically with create_function:
<?php
class A
{
public function __construct()
{
$this->addUpEchoAndReturn=create_function('$a,$b','$c=$a+$b;echo "$a+$b=$c<hr />";return $c;');
}
public function add_up_and_echo($a,$b,$c,$d)
{
$fn=$this->addUpEchoAndReturn;
return $fn($fn($a, $b),$fn($c, $d));
}
}
$x=new A();
$result=$x->add_up_and_echo(3,4,5,25);
echo "<hr /><hr />Final Result: $result";
?>
I have a class like this:
class A {
public $var = "";
function __construct() {
$this->var = "value";
}
}
And a child class like this:
class B extends A {
function __construct() {
// Is this correct?
parent::__construct();
}
function my_function() {
// Or this?
// $options is an instantiation of A.
global $options;
echo $this->var;
}
}
The problem I was having is that when I called the my_function() method, the value of var was empty. After reading on php.net for a while I found out that when a child class has its own constructor, the parent constructor is overridden which is why my variable was empty. My question is if the way I'm calling parent::__construct() is the right solution or if I should just globalize the instantiated object that I created in my script? I've done a lot of reading in comments on PHP.net and other places and I couldn't find anything concise.
With parent::method() you call the overridden method (not only the constructor), so your solution is the right one. In your case you can omit the constructor completely and just set the value, when you declare the property.
class A {
public $var = "value";
}
Additional: Global variables are ugly in every way. Use them only, if you have really good reasons to do so and never, because its more convenient.
The following "implementation" ...
$instanceOfB = new B();
$instanceOfB->my_function();
results in "value" ... as excpected.
What has been your way of calling my_function() ?
So this might sound a little convoluted. Fingers crossed I come across clearly.
I'm working in an MVC framework in PHP.
I load a controller /report/index which calls to a helper
<? class ReportController extends Controller {
public function index() {
$foo = MainReport::get_data($_REQUEST);
}
}
?>
Inside the helper
<? class MainReport extends foo {
public function get_data($_REQUEST) {
// do stuff
return $stuff_done;
}
}
?>
It I run it like ^this all's well and good. Unfortunately, I want to run it like this:
<? class MainReport extends foo {
private function do_stuff() {
// do even better stuff here!
return $better_stuff;
}
public function get_data($_REQUEST) {
// do stuff
$x = $this->do_stuff();
}
}
?>
Unfortunately... when I try and call a private function from within a class that I've called from elsewhere... (whew, that's a mouthful) ... everything dies. Dies so very very badly that I don't even get an error.
It seems obvious to me that I'm having an incredibly dorky sort of syntax issue of some sort... but how do I correctly access private functions from within a class?
Maybe something like:
self::do_stuff();
What about declaring and accessing private class variables?
private $bar = array();
Any help would be welcome.
You are calling your function from a static context,
MainReport::get_data($_REQUEST)
therefore $this does not exist while inside that function.
If you want to call another class function while inside a static context, you have to also call it statically.
i.e.
public function get_data($_REQUEST) {
// do stuff
$x = MainReport::do_stuff();
}
Alternatively, you can create an instance of your class in the original call and use the instance:
$myMainReport = new MainReport();
$myMainReport->get_data($_REQUEST);
Then your class code will work as expected
I've just found that self:: does work as well
if I want to have private class variables, I can declare and access them using
private static $foo
and
self::$foo = "foo";
additionally a private function can be accessed with
self::function_foo();
how do i call a static method from another method inside the same class?
$this->staticMethod();
or
$this::staticMethod();
self::staticMethod();
More information about the Static keyword.
Let's assume this is your class:
class Test
{
private $baz = 1;
public function foo() { ... }
public function bar()
{
printf("baz = %d\n", $this->baz);
}
public static function staticMethod() { echo "static method\n"; }
}
From within the foo() method, let's look at the different options:
$this->staticMethod();
So that calls staticMethod() as an instance method, right? It does not. This is because the method is declared as public static the interpreter will call it as a static method, so it will work as expected. It could be argued that doing so makes it less obvious from the code that a static method call is taking place.
$this::staticMethod();
Since PHP 5.3 you can use $var::method() to mean <class-of-$var>::; this is quite convenient, though the above use-case is still quite unconventional. So that brings us to the most common way of calling a static method:
self::staticMethod();
Now, before you start thinking that the :: is the static call operator, let me give you another example:
self::bar();
This will print baz = 1, which means that $this->bar() and self::bar() do exactly the same thing; that's because :: is just a scope resolution operator. It's there to make parent::, self:: and static:: work and give you access to static variables; how a method is called depends on its signature and how the caller was called.
To see all of this in action, see this 3v4l.org output.
This is a very late response, but adds some detail on the previous answers
When it comes to calling static methods in PHP from another static method on the same class, it is important to differentiate between self and the class name.
Take for instance this code:
class static_test_class {
public static function test() {
echo "Original class\n";
}
public static function run($use_self) {
if($use_self) {
self::test();
} else {
$class = get_called_class();
$class::test();
}
}
}
class extended_static_test_class extends static_test_class {
public static function test() {
echo "Extended class\n";
}
}
extended_static_test_class::run(true);
extended_static_test_class::run(false);
The output of this code is:
Original class
Extended class
This is because self refers to the class the code is in, rather than the class of the code it is being called from.
If you want to use a method defined on a class which inherits the original class, you need to use something like:
$class = get_called_class();
$class::function_name();
In the later PHP version self::staticMethod(); also will not work. It will throw the strict standard error.
In this case, we can create object of same class and call by object
here is the example
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
call a static method inside a class
className::staticFunctionName
example
ClassName::staticMethod();