I'm currently working on an own PHP-MVC-Framework (for experience purposes only).
My question: Is it possible to call a defined function or method, every time a class-method
has been called?
For example:
public function view($id) {
//Code ...
$this->view->render(__FUNCTION__);
}
What I want is:
public function view($id) {
//Code ...
//render-method is called automatically with functionname as parameter
}
I tried different methods ... but without success.
Would be great if someone could help me out with this.
Cheers,
Chris
You can use Magic Methods do achieve this behavior:
public function __call($func, $args) {
if(!method_exists($this, $func)) {
return;
}
// do some coding here
call_user_func_array($func,$args);
// do some coding there
}
private function view($arg1, $arg2) {
// and here
}
Remember: view function must be private/protected.
$obj->view("asdasd", "asdsad");
Should do ::__call(), then ::view() method
You could create a function as a liaison using PHP's ability to use variable values for execution purposes. for example:
function call($func,$param)
{
$this->$func($param);
$this->render($func);
}
$myObj->call('view',$id);
You can use a wrapper method. Call this method and pass everything else as a parameters.
Related
Ok so my question is, i have a Facebook call back function that I'm using. The callback function uses an instance as an argument facebookCallBack(LaravelFacebookSdk $fb)
The function works great,I'm using this in my auth controller in larvel , but now I want to reuse this function within the same controller something like $this>facebookReusableCallBack(LaravelFacebookSdk $fb)
I'm having issues ,i get this error facebookReusableCallBack() must be an instance of SammyK\LaravelFacebookSdk\LaravelFacebookSdk, none given.
here's a sample of my code:
public function facebookCallBack(LaravelFacebookSdk $fb) {
$this->facebookReusableCallBack();
}
public function facebookReusableCallBack() {
//All my code here
}
how can I reuse this function within my controller?
i've tried :
public function facebookCallBack(LaravelFacebookSdk $fb) {
$this->facebookReusableCallBack(LaravelFacebookSdk $fb);
}
but the argument doesn't get passed as an instance?
You don't need to define the type of a variable when you pass it in.
Method definition:
public function facebookReusableCallBack(LaravelFacebookSdk $fb) {
//some code
}
Execution within another method:
function myMethod() {
$var = new LaravelFacebookSdk();
$this->facebookReusableCallBack($var);
}
What you have done is define the type of the variable in your function definition (good) to force the type. However these are only needed in the definition.
So for your explicit example:
public function facebookCallBack(LaravelFacebookSdk $fb) {
$this->facebookReusableCallBack($fb);
}
Because $fb must be an instance of LaravelFacebookSdk when calling facebookCallBack it will be fine for facebookReusableCallBack.
hi i have a method chain in php somewhat like
<?php
auth::('username') -> is_logged() -> doSomething();
//execute something
?>
what i would like to do is if the user is not logged then not invoke the doSomething() function. One way is to unset $this but that would generate an error id there any other way to do it. Also i cant be using die() because it would stop the compiler and prevent codes written afterwards from executing. What is the best way to do it preferably without any warning or error and at the same time making as few changes as possible because of a large number of functions associated with the class.
Return NullObject which will provide empty implementation of doSomething
In PHP you only need to provide the magic __call() method, so any function call will pass.
class NullObject {
public function __call($name, $arguments) {
return $this;
}
}
To use it in your class:
public function is_logged() {
if ($this->user_is_logged()) {
return $this;
} else {
return new NullObject;
}
}
I have 2 functions, they currently are doing the same thing.. In the future, it's quite possible that I need to add more functionality to one, but at the moment they act the same.
private function GetAnswerId( $value, $fieldId )
{
// Code goes here, returns something
}
private function GetQuestionId( $value, $fieldId ); // Currently same code as GetAnswerId... But might change later!
Is there some clever way of communicating to future developers that okay this function is currently the same implementation but in the future it won't be.. I don't want to just copy the code in GetAnswerId because that's drydicoulous. but I also don't want to use the same function because that's not forward thinking.
Virtual? Abstract? something like that :S
Call your first function in your second function and expand from there:
private function GetQuestionId( $value, $fieldId )
{
GetAnswerId( $value, $fieldId );
// extra code
}
Move your duplicate functionality to base class:
class BaseClass
{
protected function getId($value, $fieldId) {
...
}
}
Use one method getId() instead of GetAnswerId() and GetQuestionId(). Later, if you will decide change functionality for question ID, just add new method to current class:
class CurrentClass extend BaseClass
{
protected function GetQuestionId($value, $fieldId) {
...
}
}
In your case, I'd add some documentation to your function explaining that it is planned to change its behavior soon and make this function call and return GetAnswerId's value.
private function GetQuestionId($value, $fieldId)
{
return $this->GetAnswerId($value, $fieldId);
}
Is there any way of identifying if a function was called from within the same class in PHP?
Besides using something like debug_backtrace ?
Update:
This is what I'm currently doing:
class Alex {
function __construct()
{
$this->internal = false;
}
function a()
{
$this->internal = true;
$this->b();
}
function b()
{
if($this->internal)
// ...
else
// ...
}
}
I 'm not sure why you would want to do that; this kind of requirement is suspicious, and usually for good reason.
That said, you can make a protected clone of the public function with an additional parameter that tells you if the caller was internal or external, and make the public version defer to the protected implementation.
class Before
{
public foo() { /* code here */ }
}
class After
{
public foo() { $this->fooCore(false); }
protected fooCore($calledFromInside = true) { /* code here */ }
// At this point you should make sure that you never call $this->foo()
// directly from inside class After
}
Not that I'm aware of. I solved a similar problem by having an extra optional parameter that passed a value when called from inside the class.
HTH :)
It is possible to debug PHP for instance in NetBeans like you can see to debugging in NetBeans. Also, you can find useful tools onsseful PHP tools, like Webgrind or Xdebug.
I tried these two ways:
(new NewsForm())->getWidgetSchema();
{new NewsForm()}->getWidgetSchema();
With no luck...
PHP does not allow you to do this. Try:
function giveback($class)
{
return $class;
}
giveback(new NewsForm())->getWidgetSchema();
It is a rather weird quirk with the language.
You can't an instanciation and a method call in one instruction... But a way to "cheat" is to create a function that returns an instance of the class you're working with -- and, then, call a method on that function which returns an object :
function my_function() {
return new MyClass();
}
my_function()->myMethod();
And, in this kind of situation, there is a useful trick : names of classes and names of functions don't belong to the same namespace -- which means you can have a class and a function that have the same name : they won't conflict !
So, you can create a function which has the same name as your class, instanciates it, and returns that instance :
class MyClass {
public function myMethod() {
echo 'glop';
}
}
function MyClass() {
return new MyClass();
}
MyClass()->myMethod();
(Yeah, the name of the function is not that pretty, in this example -- but you see the point ;-) )
If it is a static method you can just do this:
NewsForm::getWidgetSchema();
A better option in my opinion would be to use a factory method:
class factory_demo {
public static function factory()
{
return new self;
}
public function getWidgetSchema()
{ }
}
then
factory_demo::factory()->getWidgetSchema()
Of course, you get all the benefits of the factory pattern as well. Unfortunately this only works if you have access to the code, and are willing to change it.