Replies: 1 comment 1 reply
-
Magic methods are functionality of PHP itself not Laravel. So it doesn't matter what you try to resolve with the SOC if it is able to create it, it will give it to you. That means you implementation of the magic method is not set up properly. Made you a little example of correctly set up class with magic method __call; App\Services\ChuckNorrisJoke Source
<?php
namespace App\Services;
use GuzzleHttp\Client;
use Illuminate\Support\Str;
use Throwable;
/**
* @method array categories() Retrieve a list of available categories.
*
* @see https://api.chucknorris.io
*/
class ChuckNorrisJoke
{
/**
* The http client.
*
* @var \GuzzleHttp\Client
*/
protected Client $http;
/**
* List of endpoints that gave errors.
*
* @var array
*/
protected array $failedEndpoints = [];
/**
* Create new instance of Chuck Norris Joke instance.
*
* @return void
*/
public function __construct()
{
$this->http = new Client([
'base_uri' => 'https://api.chucknorris.io',
'headers' => [
'Accept' => 'application/json',
],
]);
}
/**
* Retrieve a random chuck norris joke from a given category.
*
* @param string|null $category
* @return \stdObject|null
*/
public function random(string $category = null)
{
return $this->request('random', array_filter(compact('category')));
}
/**
* Search the Chuck Norris Jokes.
*
* @param string $query
* @return \stdObject|null
*/
public function search(string $query)
{
return $this->request('search', compact('query'));
}
/**
* Make a request to the Chuck Norris API.
*
* @param string $endpoint
* @param array $query
* @return \stdObject|null
*/
public function request(string $endpoint, array $query = [])
{
if (in_array ($endpoint, $this->failedEndpoints)) {
return null;
}
try {
$response = $this->http->get("/jokes/$endpoint", compact('query'));
if (! Str::contains($response->getHeader('Content-Type')[0], 'application/json')) {
return $response->getBody()->getContents();
}
return json_decode($response->getBody()->getContents());
} catch (Throwable $e) {
if (! method_exists($this, $endpoint)) {
$this->failedEndpoints[] = $endpoint;
}
}
return null;
}
/**
* Magic method for calling endpoints based on requested methods.
*
* @param string $method
* @param array $parameters
* @return \stdObject|null
*/
public function __call(string $method, array $parameters)
{
$endpoint = Str::slug($method);
return $this->request($endpoint);
}
} and when you want to use it: use Illuminate\Support\Arr;
use App\Services\ChuckNorrisJoke;
use Illuminate\Support\Arr;
$jokes = app(ChuckNorrisJoke::class);
$randomCategory = Arr::random($jokes->categories());
$joke = $jokes->random($randomCategory);
$missingEndpoint = $jokes->missing(); // Expecting null, because the we will call the API endpoint /jokes/missing and it will give us 404.
dump(compact('randomCategory', 'joke', 'missingEndpoint')); The magic example here is If you want you can share where you define the magic method in your class to debug it :) |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I'm not sure if this is a bug or something for take into account. I'm actually trying to create a hook behaviour for classes and methods using the __call magic method. When I declare a __call magic method on a class that is automatically injected by the service container, and then try to execute a non existent method, it throws a ReflectionException "Method (*) does not exist". If I declare a method protected/private inside that class, and then I try to execute that method outside of the class (e.g. injected by the service container automatically in a controller) It executes the __call magic method (as expected).
The PHP documentation says this about __call magic method:
As you may know, __call is executed also when a method doesn't exist (not only if the method is not accessible).
am I missing something? do you think it's a bug or not? Please let me know your thoughts, because I believe it is a bug taking into account the current way PHP handle __call magic method.
Beta Was this translation helpful? Give feedback.
All reactions