Can I declare the same multiple abstract methods with different parameters? - php

Can I somehow do this in an abstract class in php:
abstract function AddFilter();
abstract function AddFilter( /*array*/ $c_array='', /*string*/ $url='')
// ... etc...
using optional parameters / how do I do this?
if i just use the second one i get 'Declaration ofContent::AddFilter() must be compatible with that of ContentGeneric::AddFilter() '
update: ok... my method is now to add a single line callback function in the extended AddFilter() which works but is ofcourse not the nicest, whatever.

No, you can't do that. PHP does not support overloading functions with different signatures like e.g. C++ does. If you want to emulate something like this, take a look at the __call() magic method.

Related

What's the best way to share methods between 2 classes, where I can freely call the methods from either, without using inheritance?

Assume yourMethod is a method you provide in your class.
Assume packageMethod is a method provided from my package (note: I'm using Laravel and a facade on the package, but it's probably irrelevant for my question).
How would you best accomplish this:
// Controller
$obj = EasyPackage::make(new YourClass);
$obj->easyMethod(); // Calls package method (probably does some stuff using the injected instance of YourClass and some of your methods)
$obj->yourMethod(); // You can still call your methods directly too! But How???
//$obj->yourInstance->yourMethod(); I don't want you to have to do this.
Basically these classes are sharing methods without the need for me to explicitly reference the property holding Your instance, as you see commented at the bottom of this example. Instead, EasyPackage should check to see if the method is public and available, first within it's own set of methods, and if not then secondly check YourClass. How do I get this to work? Is there a proper design pattern that does this that I can research?
I'm aware that I could probably achieve this using __call magic method in the package, but before I go down that road I wanted to make sure I'm not missing some other more standard approach. If the magic method is indeed the best for accomplishing this then I'm interested in seeing it used in a clean way.
This could be a decorator pattern or proxy.
Although in your example I think it is __call method, which in the easiest example can be:
public function __call($method, $arguments) {
return call_user_func_array(array($this->innerObject, $method), $arguments);
}

Method overloading in a model of Yii framework

I want to overload two methods in a model of Yii framework.
Here, I want to say that like in Java we have method overloading concept means method has same name but differs in number of parameters pass to that method. So these similar concept can apply in PHP Yii framework's model class.
In Yii model class, I want to create two methods like,
public function test(){
//method logic
}
public function test(int parameters){
//method logic
}
Is it possible to create like these? I am getting error like "cannot define same function".
What you are talking about is not supported in PHP. You could try using default values in function arguments. For eg.
function foo($int_param = 0) // do something
You could also use func_get_args. You define your function to not accept parameters and then get the arguments using func_get_args().
These approaches are suitable if there is not a lot of difference between the functions that you're trying to implement.

Global vs function vs static class method

Let's say you have a object that is unique, and it's used by all other classes and functions ...something like $application.
How would you access this object in your functions?
using a global variable in each of you functions:
global $application;
$application->doStuff();
creating a function, like application() that instantiates the object into a static variable and returns it; then use this function everywhere you need to access the object:
application()->doStuff();
create a singleton thing, like a static method inside the object class which returns the only instance, and use this method to access the object:
Application::getInstance()->doStuff();
KingCrunch & skwee: Pass the application object as argument to each function/class where is needed
...
public function __construct(Application $app, ...){
....
If there are other options please post them. I'm wondering which of these options is the most efficient / considered "best practice".
I'd pass it to all the needed methods.
i.e.
function doFoo(Application $app) {
$app->doStuff();
}
Both global and singleton considered bad and ties your code too much and this makes unit testing more difficult.
There is one rule when you are allowed to use singleton, if you answer "yes" to the following statement:
Do I need to introduce global state to my application AND I must have a single instance of given object AND having more than one instance will cause error
If you answer yes to all the 3 parts then you can use singleton. In any other case just pass all the instances to all the method who needs them. If you have too much of them, consider using something like Context
class Context {
public $application;
public $logger;
....
}
========
$context = new Context();
$context->application = new Application();
$context->logger = new Logger(...);
doFoo($context);
========
function doFoo(Context $context) {
$context->application->doStuff();
$context->logger->logThings();
}
(you can use getters/setters if you need to protect the data or manipulate it or if you want to use lazy initiation etc).
Good luck!
Singletons, God Classes, monolithic classes, etc. are all anti patterns, so I would suggest a fourth option: dependency injection. You can create an instance of application in your application via a factory (or perhaps even new if it has no dependencies, but this can end up complicating things later).
Then, any class that needs access to application can get it as a member, helpfully via the constructor. I'm sure that not every class needs access to application. Remember the Law of Demeter.
If you need some generic functionality like converting one static string to another, I suggest using php's global functions (as opposed to, for instance, a faux static class). I believe they were designed for that purpose.
Or just give it to the ones, that are interested in it. All the suggestions you made are like global variables, even if you call it not that in 2 of 3 variants.
Before it comes to that: If you want to say "Thats not possible, because everything needs it", than maybe it does too much, can too much, and/or knows too much.

PHP: Passing Interface as Parameter

In .NET I have done that I passed Interfaces as parameters in class methods. I want to know is it possible in PHP?
My scnerio is that I have a class dealing with mqin system functionality. Now I want to integrate Notification system with it. I want to keep notification system separate since it is not the main part of the system plus I can use it somewhere else. If I have the following structure:
Interface INotification
{
public set()
public send()
}
And then I do:
class MyClass
{
public setNotifier(INotification $notifier)
{
}
}
So Is it possible that I can access set() and send() here after implementing them in a class? I want to know how this C# Example work that they set parameters of an Interface type.
Thanks
Yes, it is possible, pretty much as you wrote. Example of such interface: http://api.nette.org/2.0/source-Http.IResponse.php.html#18 and example of such parameter: http://api.nette.org/2.0/source-Http.Context.php.html#32
Yes, you can do as you coded. You can find more information and examples on php.net.
Note that specifying the type in the method parameter (type hinting) is allowed (PHP >= 5), but not required.

PHP: Using a method as a callback

I was trying to use array_walk_recursive for something, and wanted to use one of the class' methods as the call back, so trying:
array_walk_recursive($TAINTED, "$this->encode()");
and variations thereof all failed. I eventually settled for:
array_walk_recursive($TAINTED, 'className::encode');
which works, but I've read on here that calling class methods in a static fashion like this is often considered poor practice. Or is this one of those situations where it's necessary?
So, is this the right way to go about it, or is there a way to put in the callback function without having to fall back on using it as a static class method?
array_walk_recursive($TAINTED, array($this, 'encode'));
I know this thread is older but by reading your words "calling class methods in a static fashion like this is often considered poor practice" I have to say that static functions are a good practice when used for the right task. Frameworks like Laravel and Symphony shows the true potential of static methods.
Anyways when you aren't afraid of using static methods you can call your method using self instead of specifying the class name that might change during development process.
array_walk_recursive($TAINTED, 'self::encode');

Categories