Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the Laravel 4.1 documentation work?

I've gotten a start with how Laravel works from its docs as well as from tutorials and SO. But I keep running into the same problem when I try to use their API/class reference.

For example, I've been able to use the URL class like this:

URL::to('string')

Which I learnt about from a tutorial. But if I look at the documentation for Illuminate\Support\Facades\URL it doesn't list a to() method.

Conversely, if I look at the documentation for Illuminate\Filesystem\Filesystem and I try to call the get() method like this:

$file = new Filesystem;
$file->get('lorem.txt'); 

I get the following error

Class 'Filesystem' not found

My questions:

  • How do I know which Classes I can use and which Methods I can call?
  • Where do I find this information?
  • Or am I just missing something about how Laravel works?
like image 881
Graham Nicol Avatar asked Dec 20 '22 20:12

Graham Nicol


2 Answers

Laravel uses a Design Pattern called Facade, it is basically an alias for the instantiated object so you can use it this way:

URL::to('string');

Instead of

$url = new URL;
$url->to('string');

Take a look at your app/config/app.php and you'll see the URL alias pointing to the Facade:

'URL' => 'Illuminate\Support\Facades\URL',

If you look at the Facade you'll see the real "internal" name of it ('url'), in the IoC container:

protected static function getFacadeAccessor() { return 'url'; }

This 'url' object is instantiated by a Service Provider somewhere, this one is binded to the IoC container in the Illuminate\Routing\RoutingServiceProvider:

/**
 * Register the URL generator service.
 *
 * @return void
 */
protected function registerUrlGenerator()
{
    $this->app['url'] = $this->app->share(function($app)
    {
        // The URL generator needs the route collection that exists on the router.
        // Keep in mind this is an object, so we're passing by references here
        // and all the registered routes will be available to the generator.
        $routes = $app['router']->getRoutes();

        return new UrlGenerator($routes, $app->rebinding('request', function($app, $request)
        {
            $app['url']->setRequest($request);
        }));
    });
}

And there you can see that 'url' is, in fact, UrlGenerator ->(http://laravel.com/api/4.1/Illuminate/Routing/UrlGenerator.html).

Here's the to() method:

/**
 * Generate a absolute URL to the given path.
 *
 * @param  string  $path
 * @param  mixed  $extra
 * @param  bool  $secure
 * @return string
 */
public function to($path, $extra = array(), $secure = null)
{
    // First we will check if the URL is already a valid URL. If it is we will not
    // try to generate a new one but will simply return the URL as is, which is
    // convenient since developers do not always have to check if it's valid.
    if ($this->isValidUrl($path)) return $path;

    $scheme = $this->getScheme($secure);

    $tail = implode('/', (array) $extra);

    // Once we have the scheme we will compile the "tail" by collapsing the values
    // into a single string delimited by slashes. This just makes it convenient
    // for passing the array of parameters to this URL as a list of segments.
    $root = $this->getRootUrl($scheme);

    return $this->trimUrl($root, $path, $tail);
}

It's a little confusing at start, but you just have to remember:

1) Find the Alias.

2) Find the Facade and get the real internal name.

3) Find the ServiceProvider to find the real class.

like image 95
Antonio Carlos Ribeiro Avatar answered Dec 22 '22 08:12

Antonio Carlos Ribeiro


When you call something like URL::to('string') you are using the Facade as you found out by inspecting the facade namespace. The facade class itself just points the request to the class it should use, in this case url, this class is bound to the Laravel IoC container in Illuminate\Routing\RoutingServiceProvider in the method registerUrlGenerator().

By studying the binding you can see that when you use the URL facade you are actually using the class Illuminate\Routing\UrlGenerator.

The API documentation isn't actually as useful in a framework like Laravel where facades provide access to classes via an IoC container and thus abstracting the implementation from the calling code. This makes it very hard to actually find where the class you are actually using is. I resort to running searches on the vendor directory. If the facade returns url. I search for $this->app['url'] that will find the binding, I can then follow the trail to the classes that are actually used. Failing this search, I would resort to searching simply for ('url within the vendor directory.

As to your second question, if you want to instantiate a class that is namespaced you must use the namespace.

$filesystem = new Illuminate\Filesystem\Filesystem();

You wouldn't actually need to do this as this class is bound to the IoC container using the alias files that via the facade File gives you full access the class via static calls.

Alternatively if you want your own copy of the Filesystem class, it would be better to use the IoC container to get it.

$filesystem = App::make('files');
like image 33
David Barker Avatar answered Dec 22 '22 08:12

David Barker