Lets say I have a method:
public function createFoo(Foo $foo, $isPremiumFoo=false);
In hindsight, it was a little silly to have that $isPremiumFoo
flag argument hanging off the end. So we moved it into Foo
and now I'd like to remove it from the method signature. But I don't want to do it all at once since this is a public method and is out in the wild being used. I'd like to @deprecate
it to alert users to the fact that they should stop using it and then eventually remove it. Since you can't overload methods in PHP, how can I deprecate just that method argument and not the entire method?
You could do something like this
class Foo {
}
class Bar {
public function createFoo(Foo $foo, $isPremiumFoo=false) {
if (count(func_get_args()) > 1) {
$warn = "isPremiumFoo is deprecated and will be removed
in a future release";
trigger_error($warn, E_USER_NOTICE);
}
// continue with the implementation
}
}
$foo = new Foo();
$bar = new Bar();
$bar->createFoo($foo); // wont trigger the notice
$bar->createFoo($foo, true); // will trigger the notice
$bar->createFoo($foo, false); // will trigger the notice
<?php
class Foo
{
private $isPremium = false;
public function setPremium($premium)
{
$this->isPremium = $premium;
}
public function isPremium()
{
return $this->isPremium;
}
}
function createFoo(Foo $foo)
{
if (func_num_args() > 1) {
$isPremium = func_get_args()[1];
$foo->setPremium($isPremium);
}
return $foo;
}
$foo = new Foo();
var_dump(createFoo($foo)); // false (because default value is false in the class)
$foo->setPremium(true);
var_dump(createFoo($foo)); // true (the new way - you can manipulate it as an object property.)
var_dump(createFoo($foo, false)); // false (even thought you have manipulated it, it's backwards compatibility for users who are using the second param)
var_dump(createFoo($foo, true)); // true (again backward compatibility)
The explanation is in the code comments. Basically, there isn't anything that stops you to call a function with more params than it recieves. So you can safely remove it from the signature and check for it in the function body.
Using that logic, you can show the users some kind of warning, if a second parameter is provided. Your new users, using the new API may not even be aware that a second parameter ever existed.
I've done this same thing. The approach we use in our team is simply to update the docblock.
Then in the IDE's, when someone gets a popup they can clearly see that it was deprecated and we don't use it. As time progresses, we finally remove it all together.
Example:
/**
* Create Foo
*
* @param Foo Description
* @param bool Deprecated, use Foo->setIsPremium(true|false)
*
* @return Bar
*/
public function createFoo(Foo $foo, $isPremiumFoo=false);
Hopefully this helps some.