#!/bin/bash # nginx Startup script for the Nginx HTTP Server # this script create it by ivan at 2010.12.29. # # chkconfig: - 85 15 # description: Nginx is a high-performance web and proxy server. # It has a lot of features, but it's not for everyone. # processname: nginx # pidfile: /var/run/nginx.pid # config: /etc/nginx.conf
It’s not uncommon to have tens, if not hundreds of views in a Laravel application. Something that soon gets out of hand is the various references to routes. Think about how many times you’ve done something like this in your blade views:
If for whatever reason we have to make a change to either the route alias or default query string values you’ll soon find yourself doing mass string replacements across your entire application which brings the risk of breakage within many files.
What can we do to possibly better handle this? There are a couple of different approaches.
As you can see with either approach, the view now doesn’t care about how we determine the URL, just that a URL is returned. The beauty to this is should you have to adjust any routes you only have to edit two files, not hundreds.
In the latest Laravel 5.6.12 Release a new signed URLs feature was introduced. In this article, we’ll work on enabling signed URLs in an application and look at a few options of how to use them.
Setup
First, you’ll need to run composer update laravel/framework in your terminal to pull the latest changes.
Second, you’ll need to add the new ValidateSignature to your route middleware in /app/Http/Kernel.php.
That’s it! Now you can start adding signed URLs to your application.
Starting Point
Let’s say we have an event planning application that we let users RSVP to upcoming events. We want to email all users a link so they can quickly respond “yes” or “no” if they are going. However, we don’t want to force them to log into the application again if they happen to be logged out.
Currently, we have the following event.rsvp route in our routes/web.php file.
1 2 3
Route::get('event/{id}/rsvp/{user}/{response}', function ($id, $user, $response) { // Add response from user for event. })->name('event.rsvp');
We can see that a curious or malicious user will be easily able to change any variables in the URL, which is far from ideal.
Signing a URL
Now that we have a prime candidate for a signed URL let’s add the signature handling.
First, we’ll need to add the signed middleware to our route definition.
1 2 3
Route::get('event/{id}/rsvp/{user}/{response}', function ($id, $user, $response) { // Add response from user for event. })->name('event.rsvp')->middleware('signed');
Next, we’ll change our Url::route() to Url::signedRoute() in our application.
Now by using this signed URL if that same “curious” user tries to tamper with the user id, changing it from 100 to 101, or the signature ending with 4 to 5 Laravel will throw an Illuminate\Routing\Exceptions\InvalidSignatureException.
Temporary URLs
In addition to just signing a URL, Laravel gives us a great way to add an expiration to a signature as well. If we want the link to expire in 1 hour from generation, we can update our code to the following.
Eloquent ORM seems like a simple mechanism, but under the hood, there’s a lot of semi-hidden functions and less-known ways to achieve more with it. In this article, I will show you a few tricks.
There is a magical place called boot() in an Eloquent model where you can override default behavior:
1 2 3 4 5 6 7 8 9 10 11 12
classUserextendsModel { publicstaticfunctionboot() { parent::boot(); static::updating(function($model) { // do some logging // override some property like $model->something = transform($something); }); } }
Probably one of the most popular examples is setting some field value at the moment of creating the model object. Let’s say you want to generate UUID field at that moment.
But did you know that at this point we can already add where or orderBy? For example, if you want a specific relationship for some type of users, also ordered by email, you can do this:
There are a few “parameters” of an Eloquent model, in the form of properties of that class. The most popular ones are probably these:
1 2 3 4 5 6
classUserextendsModel{ protected$table = 'users'; protected$fillable = ['email', 'password']; // which fields can be filled with User::create() protected$dates = ['created_at', 'deleted_at']; // which fields will be Carbon-ized protected$appends = ['field1', 'field2']; // additional values returned in JSON }
But wait, there’s more:
1 2 3 4 5 6
protected$primaryKey = 'uuid'; // it doesn't have to be "id" public$incrementing = false; // and it doesn't even have to be auto-incrementing! protected$perPage = 25; // Yes, you can override pagination count PER MODEL (default 15) const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; // Yes, even those names can be overridden public$timestamps = false; // or even not used at all
And there’s even more, I’ve listed the most interesting ones, for more please check out the code of default abstract Model class and check out all the traits used.
6. Find multiple entries
Everyone knows the find() method, right?
1
$user = User::find(1);
I’m quite surprised how few people know about that it can accept multiple IDs as an array:
1
$users = User::find([1,2,3]);
7. WhereX
There’s an elegant way to turn this:
1
$users = User::where('approved', 1)->get();
Into this:
1
$users = User::whereApproved(1)->get();
Yes, you can change the name of any field and append it as a suffix to “where” and it will work by magic.
Also, there are some pre-defined methods in Eloquent, related to date/time:
A little more complicated “trick”. What if you have forum topics but want to order them by latest post? Pretty common requirement in forums with last updated topics on the top, right?
First, describe a separate relationship for the latest post on the topic:
Notice that the function name is different – it’s not orderBy, it’s sortBy.
12. Default ordering in global scope
What if you want to have User::all() always be ordered by name field? You can assign a global scope. Let’s go back to the boot() method, which we mentioned already above.
1 2 3 4 5 6 7 8 9
protectedstaticfunctionboot() { parent::boot();
// Order by name ASC static::addGlobalScope('order', function (Builder $builder) { $builder->orderBy('name', 'asc'); }); }
Read more about Query Scopes here.
13. Raw query methods
Sometimes we need to add raw queries to our Eloquent statements. Luckily, there are functions for that.
16. Create additional things when creating a model
We all know this Artisan command:
1
php artisan make:model Company
But did you know there are three useful flags to generate related files to the model?
1
php artisan make:model Company -mcr
-m will create a migration file
-c will create a controller
-r will indicate that controller should be resourceful
17. Override updated_at when saving
Did you know that ->save() method can accept parameters? As a result, we can tell it to “ignore” updated_at default functionality to be filled with current timestamp. See this:
I mean, the update is performed in the database, but what would that $result contain?
The answer is affected rows. So if you need to check how many rows were affected, you don’t need to call anything else – update() method will return this number for you.
19. Transform brackets into an Eloquent query
What if you have and-or mix in your SQL query, like this:
… WHERE (gender = ‘Male’ and age >= 18) or (gender = ‘Female’ and age >= 65) How to translate it into Eloquent? This is the wrong way:
// Next, we will create the view instance and call the view creator for the view // which can set any data, etc. Then we will return the view instance back to // the caller for rendering or performing other view manipulations on this. $data = array_merge($mergeData, $this->parseData($data));
Over the past few years JSON has taken over as the king of data interchange formats. Before JSON, XML ruled the roost. It was great at modeling complex data but it is difficult to parse and is very verbose. JSON really took off with the proliferation of rich AJAX driven sites as it’s a very human readable format, quick to parse and its simple key/value representation cuts out all the verbosity of XML.
I think we could all agree that writing less code that in turn requires less maintenance and introduces less bugs is a goal we would all like to achieve. In this post, I’d like to introduce you to a little known interface that was introduced in PHP 5.4.0 called JsonSerializable.
Before the JsonSerializable interface was available, returning a JSON encoded representation of an object for a consuming service meant one of two things.
The Ugly
The first approach was to construct a data structure outside the object that contained all the data that we wanted to expose.
We used an array here to hold the data from the Customer object that we wanted to encode, but it could just as easily have been an StdClass.
This approach was flexible and served its purpose in very simple situations where we knew that the Customer object wasn’t going to change and we were only going to need Customer data in this format, in this one place. We also had the option of adding data to this array from other sources if we needed to.
However as we’ve all experienced at one time or another, the assumptions we’ve made can be proven false at a moments notice. We might get a requirement that asks us to add more data to the Customer class. That new data will need to be returned to the consuming service and we’ll want to do this in numerous places.
As you can imagine, this approach quickly becomes troublesome. Not only do we have to duplicate this array code all over our application, we have to remember to update all those instances when more changes inevitably come in. There is another way though, that will help us nullify some of these issues.
The Bad
Luckily we were smart when the first change request came in and we realized that duplicating our array was going to be a nightmare, so what we decided to do was internalize that encoding functionality in our object, removing the maintenance issues and reducing the likelihood of introducing bugs.
$customer = new Customer('customer@sitepoint.com', 'Joe');
echo$customer->toJson();
Now if any more change requests come in that want more data to be added to and returned from the Customer object we can just update the toJson method.
This approach has it’s own drawbacks, though. Anyone else that comes along and wants to use our Customer needs to be aware of this toJson method because it’s not something that is easily checked for, so we’d need accurate documentation. We also have to remember that this method returns JSON now, (though we could move the serialization outside the method). This makes combining Customer data with other sources of data more awkward because we have to be careful not to encode the result of this method again as that would cause some nasty bugs.
The Good
Finally, enter the JsonSerializable interface. This gives us all the flexibility of the Ugly scenario with the maintainability benefits of the Bad scenario. Though to use this interface you will need to be running PHP 5.4.0+ which you really should be doing anyway, as there are many improvements over older versions.
$customer = new Customer('customer@sitepoint.com', 'Joe');
echo json_encode($customer);
As you can see, we implement JsonSerializable by adding the interface to our class and then adding a jsonSerialize method to the body of our class to satisfy the interfaces contract.
In the jsonSerialize method we construct and return an array of the object data, just as we did with the other examples. Once again if anything changes then we can just update this one method. You’ll notice that the jsonSerialize method just returns an array.
The magic comes when you want to trigger this method, all we have to do now is json encode an instance of this class and this method will be called automatically, the array of data returned and then encoded! Now that the class implements an interface we benefit from being able to check if this class is an instanceof JsonSerializable. If you wanted you could also type hint in methods to make sure a JsonSerializable interface is passed.
Summary With this simple implementation, we’ve removed duplication, decreased the amount of maintenance and reduced the chances of introducing bugs. We’ve also made it trivial for another person using our code to test for the ability of the object to be encoded by checking if it’s an instance of JsonSerializable.
The examples above are of course contrived, however, I hope I’ve managed to demonstrate the benefits of using this interface and inspire you to go ahead and use it yourself.