Issue
I have a function beforeMarshal () located in ModelTable.php. This function executes correctly before the request data is saved however I get php warnings each time the data is saved.
public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
$ip = $data['ip'];
$data['iplong'] = ip2long($ip);
}
Warning (4096): Argument 1 passed to App\Model\Table\ServersTable::beforeMarshal() must be an instance of App\Model\Table\Event, instance of Cake\Event\Event given
Warning (4096): Argument 2 passed to App\Model\Table\ServersTable::beforeMarshal() must be an instance of App\Model\Table\ArrayObject, instance of ArrayObject given
Warning (4096): Argument 3 passed to App\Model\Table\ServersTable::beforeMarshal() must be an instance of App\Model\Table\ArrayObject, instance of ArrayObject given
If I set debug to false everything is fine, but this isn't a great solution.
Solution
It's probably a namespace issue. The error is that the function wants a precise type of object and it receives an other one.
I'm assuming beforeMarshal() is your own custom function and it is placed in the namespace App\Model\Table (as it belongs to the ModelTable class).
Furthermore, you are probably calling it from an other file, where you haven't specified the namespace, so it considers itself in global namespace.
either
- type hint the right object types in your function definition
- globally
usethe right object type inModelTable.php
precise type hint
change your function definition to:
public function beforeMarshal(\Cake\Event\Event $event, \ArrayObject $data, \ArrayObject $options)
notice the backslashes. They instruct the function to start at global namespace when considering object types.
global use
at the very top of your ModelTable.php script (or the one containing the function) add this:
use
Cake\Event\Event,
ArrayObject;
so that in the whole script, any use of the Event and ArrayObject types will use the right one without specifying the whole name each time.
Which one to choose
opinions follow
I prefer to use use at the top of my scripts. It prevents any kind of misuse of types in this specific script, and when I have to change ALL\Templating\Parser to ALL\Parser I only have to do it at one place.
specifying the whole object namespace path each time is bothersome and a little bit more error-prone, but may have advantages; I haven't experienced them and haven't stopped the global approach since I started using it.
Answered By - Félix Adriyel Gagnon-Grenier
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.