Clicky

Laravel Tips, Tricks, & Workarounds for beginners

I’ve been working with Laravel for a few weeks now and have encountered a bunch of interesting problems/confusions that are not explicitly explained anywhere. Well, either that, or I just overlooked it easily. Hope this helps you!

I noted some common errors and overlooks. If some of it seems very elementary or basic, that’s fine. The way I compiled this list was by watching what I googled, what problems I had and others had, and put my solution/answer here. It’s not perfect and you can definitely find this stuff elsewhere as well. Why bother then? Because the more stuff explaining the solutions is online, the better the chance of a noob finding it. As was my case, I had some issues with many of these. I’ll probably add some new ones as I go along in the next week or so.

Pretty URLs

To enable pretty URLs, all you need to do is go to your application/config/application.php file, look for Application Index and erase the “index.php” between the quotes (leave empty quotes). This should trigger the pretty URLs. If it doesn’t work, use the htaccess file:

<IfModule mod_rewrite.c>
     RewriteEngine on

     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d

     RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

If THAT doesn’t work, you might need some extra help that I can’t provide ;)

Changed your ‘key’ and now you’re getting an error?

Getting an error, something about “unserialize”:

unserialize() [function.unserialize]: Error at offset 0 of 224 bytes

Spot on? Alright. Just go clear your cookies and cache in your browser. Your problem should be solved :)

Installing Laravel On Shared Hosting or Hosting Without “VirtualServer” access

Oooh, tough one. No, not really. On most shared hostings (that allow PHP, MySQL etc. and may have CPanel), you will have a “home” directory which will contain “public_html” or “www” (and perhaps “public_ftp” and others). Upload all of your files (Laravel, Application, etc.) to the “home” directory. Upload your “public” files into “public_html” or whatever equivalent you have.

Go to your paths.php file (that was included with laravel)  in your “home” directory and open it. Find the section that says “The path to the public directory” and change the variable to say “public_html” or “www” instead of the default “public”. You shouldn’t encounter any permission errors, but if you do, your best bet is asking your hosting provider about it.

This is how you change your public directory wherever you are, not just on shared hosting. If you want to, for example, have a public directory in a subfolder, you can use this same method.

 Submitting A Form To The Same Page (404 and other issues)

It sometimes happens that you want to have a page, let’s say “login” or “upload”. And what you want to do is have a  form on that page. Now for the sake of validation or just keeping stuff on the same page, you want to submit to that same page ie. site.com/login will submit to site.com/login.  Now, you’re faced with an issue. When you submit your form. You get a 404. Here’s what probably happened. Look into your routes.php file:

Route::get('login', function(){
	return View::make('account.login');
});

Route::post('login', array('as'=> 'login', 'do'=> function(){
	$username = Input::get('username');
	$password = Input::get('password');
	$authAr = array(
			'username' => $username,
			'password' => $password
		);
	if (Auth::attempt($authAr)){
		return Redirect::to('home');
	}
	else{
		return Redirect::to('login')
		->with('login_errors',true);
	}
}));

Here’s what I want you to notice. I have two separate entries for login. One if I’m hit with a regular or get request and one if it’s a post. You’d usually just use Route::get for any and all pages to bring them up. It doesn’t necessarily mean you’re getting “get” requests. It’s just a standard route.

But if you DO use a form and get a 404 after submitting a form, chances are, you just don’t have a POST route setup for your page! :)

Also, this is basic laravel login form.

Authentication User Variable

You may already know that when you do that neat thing up there for logging it (attempting to login and succeeding), you’ll have a neat “Auth” object available to use for whatever. What’s interesting is that your Auth class will synchronize with your models.

Let’s say you have a User model (which you will, if you do any sort of authentication). And let’s say that model has certain methods. If you wanted to call up the user class normally you would do this:

$user = User::find($id)
// or
$user = User::where('username', '=', 'user')->first()

Once you do that, you’ll instantly have access to all of the user methods which may be (depending on how you set it up): function get_option(), function set_password(), function sister_user(), function create_user_gravatar()

or whatever of that sort so you can have it accessible via your class like so: $user->sister_user(), $user->create_user_gravatar().

Now, what do you do when you authenticate? You can use all of those methods straight from the authentication class:

Auth::user()->sister_user();
Auth::user()->create_user_gravatar();

What You’re Not Told About File Uploads

You’re not told that file uploads are easy, when you know what you’re doing. First of all, you need to know how to setup a file upload form. Are you already familiar with basic forms? Here’s a file upload form:

{{ Form::open_for_files('path/to/destination', 'POST') }}
 {{ Form::file('file_upload') }}
{{ Form::submit('Upload' }}

That’s basically it, now you just need to route it correctly (as above). So create a Route::post for your upload page and here’s what little line uploads the file for you:

Input::upload('file_upload', "uploads/", 'filename');

Sweet. So, here’s what happens. The first argument (‘file_upload’) is the field you used in the form. The second is the directory. Your directory STARTS where your “application”, “laravel”, “bundles” folders are, so not in the public folder. The third argument is the name you want to give the file to save. It can be anything.

Authentication Errors

This was a hard lesson for me and it took me forever to figure out. Once you read it you’ll wonder why the hell it took so long. Maybe I didn’t sleep well. Maybe Pandora put on some bineural beats that threw me off but here goes.

The basis of Laravel authentication is its Authenticator which takes in two variables: input and rules. You can read more about both online, somewhere, google it. But here’s what I want to pass along to you guys:

//let's send off an invite
            $input = array(
                'email_address' => Input::get('email_address')
             );
            $rules = array(
                'email_address' => 'required|email'
            );

            $v = Validator::make($input, $rules);
            if($v->fails()){
                return View::make('page.index')->with('errors', $v->errors);
            }

            else{
}

Check that out. First, you can pass along input in an array. OR you can do Input::all() which will make a neat array for you to put into the validator. Second, you should pass your rules in an array matching to the first array. See how both arrays say “email_address”? That’s because they correspond to each other.
Last, but not least, passing errors. To pass an $error variable, you need to pass it via “->with” (which passes vars to your template) that includes ‘errors’ and we will fill those errors with $v->errors. Don’t assume that passing along just $v will work out the box. IF you do pass it along without ->errors, you will have to address it in your template where every time you want to display an error you will have to add ->errors. Here’s how to show errors:

 @if($errors->first('email_address'))
        {{$errors->first('email_address')}}
       @endif

The SESSION Object And Settings

Laravel has a neat SESSION:: object that has some neat properties. First of all, I think it’s best place to store TEMPORARY user settings. For example, do you have multiple views of your site? Such as, “condensed” or “expanded” but you don’t want to save that as a temporary setting? Session is your friend. Do you want only some “tags” of stuff to show up for your user? Great, use a session.

Why a session? Because a session is persistent across all your pages until that said session expires (which is the same as logging out basically). Here’s how to use it:

Session::put('setting', 'settingoption');

Sweet. Here’s how to retrieve it:

Session::get('setting');

:) Let’s move on..

Eloquent Throwing Errors or Not Pulling Data You Know Is There?

Happened to me too. Let’s create an example. Let’s say we have a column named “lastName” in our users table and we want to pull it up but for some reasons we’re getting blanks!

$users = User::all();
foreach($users as $user){
echo $user->lastName;
}

What’s up with that, right? Easy. When dealing with Eloquent’s objects, you have to lowercase everything. This is how the correct query would look:

$users = User::all();
foreach($users as $user){
echo $users->lastname;
}

One more thing. What if we want to sort those users? Ah, well, we should just do an “order_by”, correct? Yep! :) Following our previous logic, let’s lowercase everything:

$users = User::order_by('lastname', 'DESC')->get();

Except…that didn’t work did it? Here’s what happened. Eloquent requires lower case for its objects; however, whenever you use this query or something similar where you have to pass the name of the column as a string, the column name should just as it appears in your database. In this case, with a capital “N”

$users = User::order_by('lastName', 'DESC')->get();
$users = User::paginate(100, array('id', 'lastName'));

And so on.

Another reason could be that you’re not using “get()”. If you’re retrieving all kinds of data. If you ommit “get()” from your query, you may not only end up getting only SOME results, but you may end up getting errors. I learned this the hard way and it’s especially true for related data models.

Speaking of Pagination

When you use Laravel’s pagination, an interesting problem may hit you. You can get a slew of “non objects” and “not a Query” errors. But that’s okay. Here’s what most likely happened:

$users = User::paginate(50, array('id', 'username'));
foreach($users as $user){
echo $user->id;
}

Look familiar? Okay, here’s what happened. To retrieve paginated data, you’ll have to call up the “results” of the object like so:

$users = User::paginate(50, array('id', 'username'));
foreach($users->results as $user){
echo $user->id;
}

Why? Because your object now holds some extra paginate-only methods such as “links()” which will create a pagination menu ($users->links())

(My) Common Reason For Failed Redirects

I’ve hit my head against the wall plenty of times. When you’re doing a redirect or making a view via routes, don’t forget:

//you have to use
return
//with your redirect
return Redirect::

It’s fine. I’ve done it several times. When do you know you’ve done this? You’re coming to a page that’s supposed to redirect but it doesn’t. You’re left with a blank page and everything in your code SEEMS fine. Except that pesky return!

Multiple Where

One thing you may not know about Eloquent is that if you want to chain together several where statements, it’s not a problem. Looking for the equivalent of “AND WHERE” in eloquent. Here is it:

$user = User::where('firstname', '=', 'antonin')->where('lastname', '=', 'januska')->first();

Easy as peas. That’s the saying…right? Basically, you can add as many where statements as you need to via chaining them together. You may also use or_where, where_not_in, and others in a similar fashion.

Resources

 

About Antonin Januska

Antonin Januska of "AntJanus" is a Web Developer and Designer, currently working as both a freelancer and a Lead Developer at a Houston search marketing agency. Antonin is an active member of many social media networks including Facebook, Twitter, and Google+. You can also check out my repositories on Github.

Comments

  1. Your Eloquent examples don’t actually call get() or a similar function, so no data will be returned.

  2. Also note this error, you are calling $users instead of $user, still very good tips!
    Especially the one about the unserialize() error gave me some headaches.

    $users = User::all();
    foreach($users as $user){
    echo $user->lastname;
    }

  3. Just wanted to mention my experience on a shared host – I’m using a subdomain and didn’t want to drop laravel into the root, but rather into the subdomain (/public_html/subdomain). I created the subdomain and pointed it to “/public_html/subdomain/public”. Works fine, at least with CPanel.

    • interesting. would that folder be accessible via your main site? ie. /public_html/ refers to example.com, so example.com/subdomain, would that pull up laravel or is that hidden?

  4. Thx for the article, saved me a lot of headache, especially with that pagination thing.

  5. Thx!

  6. Thank’s to correct blade code:

    From :

    {{ Form::open_for_files(‘path/to/destination’, ‘POST’ }}
    {{ Form::file(‘file_upload’) }}
    {{ Form::submit(‘Upload’ }}

    To:

    {{ Form::open_for_files(‘path/to/destination’, ‘POST’) }}
    {{ Form::file(‘file_upload’) }}
    {{ Form::submit(‘Upload’) }}

  7. Abed Halawi says:

    When using User::find($id)->first(); it always returns the first User in the database table regardless of the $id which is not the expected output. User::find($id) is enough to get the indicated user as [method] find($id) uses first() implicitly (http://laravel.com/api/source-class-Laravel.Database.Eloquent.Model.html#226)

  8. Natan Shalva says:

    thanks you so much ! i spent hours on FORM 404

  9. Jason Judge says:

    Some great tips there. In all the documentation I have seen so far, the instructions tend to involve installing and then hacking away at application/* to get things working. That always concerned me – how would you upgrade without overwriting your code?

    Your examples show how easy it is (and essential IMO) to split the framework up into blocks and put those blocks where relevant. If you have no control over your web hosting root, then simply copy the contents of public/ into your web root. Then put the full installation into another folder – outside the web root *if* you can and *if* it can be executed from there, but otherwise inside the web root under a directory that you can protect from web access (e.g. laravel-core/). Then in your root index.php, change the require(‘../paths.php’) line to require(‘new/path/to/your/paths.php’). Then in paths.php, set $paths['public'] to point to your web root folder (the paths are all relative to the files that they are in). And that gets it working on shared or restrictive hosting.

    Now, the application/ folder and all its contents can be duplicated to another folder for playing with. Just point to it in paths.php ($paths['app']) as a relative path, and you no longer have your application within the main Laravel core folder. That makes upgrading Laravel many times easier.

    – Jason

Trackbacks

  1. [...] your articles. If you’re talking about Laravel, link to the article you’re talking about it so that the user can read more on [...]

  2. [...] Laravel Tips, Tricks, & Workarounds for beginners Antonin Januska , Aug 2012 [...]

Add Your Comment