Getting started quickly with logging in Laravel

You probably know that feeling when something is broken and you don’t know why. It might be a simple bug, but it also might be something more serious. That uncertainty can be frustrating and nerve-wracking.

We can improve our situation with logs. For any application you build, it’s important you ensure you have effective logging configured, regardless of the language or framework that you use. When you set your logs up properly, you can use them to quickly debug problems and monitor performance.

To help you get there, Scalyr created a series on logging with different techs. Some of the earlier articles in this series looked at the basics of getting started with logging in Python, Angular, and PHP. And in this article, I’m going to help you get started quickly with logging in Laravel.

What Is Laravel?

Before we get started with logging, let’s take a moment to talk about what Laravel actually is.

Laravel is a popular PHP framework that focuses on making the lives of developers as productive as possible (at least while coding). The creator of Laravel, Taylor Otwell, has worked hard to ensure that the syntax is clean and clear, allowing anyone who uses the framework to move from idea to solution as quickly as possible. The framework has excellent documentation and a strong, helpful developer community.

Like other features of the framework, logging in Laravel is expressive and easy to use—and it works straight out of the box. The services provided allow you log to local files, send an email, or even message your whole team in Slack. Also, Laravel leverages a powerful PHP logging library called Monolog, which provides powerful handlers for logs. You can use the developer-friendly configuration of Laravel to leverage these handlers and create a bespoke logging experience.

Getting Our Project Up and Running

Before you can get started with logging, you need to get a local version of Laravel up and running on your machine. There are full installation details on the Laravel website to help you do this, but let me share some advice here, too.

The smoothest way to install is first to set up PHP and Composer on your machine. Composer is the package manager for PHP, and if you’ve used npm for Node packages or pip for Python then this will be familiar. With Composer installed, you can install the Laravel installer globally as follows:

composer global require laravel/installer

Once you’ve installed the utility, you can use it to get your project up and running. For this article, I’m going to call my project logging.

laravel new logging

And there it is—a completed application installed:

Once all of the dependencies have been pulled down and installed, you can change directory and use Artisan to serve your project locally. Artisan is the command-line tool for Laravel—it’s incredibly powerful and is an essential tool in any Laravel developer’s toolkit.

php artisan serve

Now, navigate to the address listed, 127.0.0.1:8000, and you should see the Laravel base project display in your browser.

The Simplest Laravel Logging That Could Possibly Work

Now that your application is up and running, let’s do the simplest possible logging. In your text editor, open up the routing file routes/web.php. To log, you’re going to use the Log facade (we’ll see more of this later). So just below the opening PHP tag, add this:

use Illuminate\Support\Facades\Log;

The only other piece of code in the file is the route:

Route::get('/', function () { return view('welcome'); });

This code is saying when the route / receives a GET HTTP request, it should resolve the function. As you can see, that function is simply returning the welcome view, which is the page you saw above. To log every time that a user arrives at this page, simply update the code to something like this:

Route::get('/', function () { Log::info('A user has arrived at the welcome page.'); return view('welcome'); });

Check your application is still serving and visit 127.0.0.1:8000 again. If all has gone well, nothing should have changed for the user, but Laravel will have logged this event. And if you open up storage/logs/laravel.log, you’ll be able to find a line to this effect:

[2019-05-08 14:16:39] production.INFO: A user has arrived at the welcome page.

And that’s it! You have successfully logged an event in Laravel.

Laravel Project Structure

You’ll find that Laravel is quite opinionated about the structure of the projects you create with it. The framework follows a model-view-controller (MVC) architecture, and if you stick to the structure, then all of the auto-discovery features will work seamlessly.

Here’s the Laravel file structure:

While we’ll look at other parts of the framework throughout this article, the most relevant file for us will be the logging.php file in the config directory. Let’s open that up now and take a look.

logging.php: The Config File

<?php use Monolog\Handler\StreamHandler; use Monolog\Handler\SyslogUdpHandler; return [ 

The config file for logging starts by importing the Monolog handlers. These will be used throughout the logging process, but it’s mostly the framework itself that will use them. Laravel has some helpful methods that will allow you to log without interacting much with this library directly.

Once the config file has imported Monolog, the rest of this file returns an associative array that defines the configuration options for logging in this project.

The first top-level key is default, which, as the name suggests, sets the default logging channel: As we’ll see later, you can configure this using environment variables, allowing different solutions for your development and production systems. If you’ve been following along, here is what the default key looks like in the app created above:

'default' => env('LOG_CHANNEL', 'stack'),

The second is the configuration for log channels.

Log Channels in Laravel

In Laravel, a channel is a log driver with some configuration. You can provide as many different channels for your logs as you would like.

Here, we’re using the single driver to manage my ‘not-urgent’ channel, while we’re using the slack driver to look after my ‘really-urgent’ channel:

'channels' => [ 'not-urgent' => [ 'driver' => 'single' ], 'really-urgent' => [ 'driver' => 'slack' ] ]

The initial configuration gives the scaffolding for a wide variety of channels covering most of the common use cases. Here are the available channel drivers and a brief description of what they do, as described in the Laravel documentation:

The Log Stack Channel

You may want certain log messages to go to more than one place. Let’s say you want to send a message to Slack, log the message in your rotating daily logs, and have an email sent to your client. Laravel provides the stack driver for this purpose:

 'stack' => [ 'driver' => 'stack', 'channels' => ['daily', 'slack'], 'ignore_exceptions' => false, ],

The channel name can be anything you’d like, but in the default configuration, this is simply set to stack. In the configuration array, you pass the driver as stack and an array of the channels you’d like to send to. As can be seen in my example above, I’m sending to the daily channel and the Slack channel. You have to define both of these in the configuration file to be valid. Now, any log message sent to the stack channel will go to the channels in the array.

You may notice the extra configuration option set in the array. Since the aim of the Laravel maintainers is to be as expressive as possible, the purpose of the new option won’t surprise you. By default, Laravel will ignore exceptions in PHP. So you’ll use this option to log exceptions to help with debugging.

As you can imagine, there are more options to change logs than we will explore here. For a more comprehensive exploration, the Laravel documentation is a good place to start.

Log Levels

At this point, let’s talk about log levels. Monolog supports all eight of the logging levels defined in the RFC 5424 specification: emergency, alert, critical, error, warning, notice, info, and debug. If you’re not familiar, it’s a list of descending seriousness. The framework itself declares logging events at different levels, and as you’ll see, you can too.

return [ ... 'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'critical', 'days' => 14, ], ... ];

When configuring a logging channel, you can set the minimum level of event you want to log. The configuration above will log events that are emergency, alert, and critical, but it will discard any events at the lower levels.

Logging in the Environment File

You’ll no doubt have different needs depending on the environment you’re logging in. It makes sense to log all events to a local file while you’re debugging locally. But on a production machine, this can quickly get unwieldy. A large log file that lists everything that has happened may not be useful in diagnosing a problem quickly and effectively.

Likewise, you probably won’t want to send a Slack message to your team every time you forget a semicolon. To help with these environment-specific configurations, we have the .env file in the root of the directory.

In this file, there’s a list of keys and values. By convention, these are in all caps, and words are separated by underscores, like this:

LOG_CHANNEL=stack

When set, any part of the Laravel application will be able to access this through the env() function. This function returns the value of an environment variable. You can set it to return a default but pass a second parameter. Otherwise, it will return null.

return [ ... 'default' => env('LOG_CHANNEL', 'daily') .. ];

In this case, the default channel will be whatever you have assigned in the environment file. If the relevant key, LOG_CHANNEL, is not present, then the env function will return the second parameter, daily.

Note that there will be cases in which you don’t want to pass a default value:

return [ ... 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ], ... ]; 

In this instance, we only want to send to Slack when the webhook URL has been defined in the .env file. This key doesn’t exist by default. And so to set up Slack, we’ll need to add a new line to that file with this key and the correct URL from Slack.

Laravel’s Default Logging Configuration

In a moment, we’re going to talk about sending messages to the log channels. But before we do, let’s recap. So far, we’ve explored all of the basic configuration options, as well as some of the more advanced ones. Now, I want to follow the thread of how the application we set up is configured out of the box.

return [ 'default' => env('LOG_CHANNEL', 'stack'), 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['daily'], 'ignore_exceptions' => false, ], ... 'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', 'days' => 14, ], ... ];

I’ve extracted the relevant parts from the configuration array above. We can see the default channel is set using the environment variable. Or if that key is missing, it will default to stack.

The stack channel is only pushing messages to a single channel—the daily channel.

The daily channel is configured with a path where log messages will be written to. Its level is set to debug, so it will log all levels of error. The days setting lets Laravel know how many days’ worth of logs to store before it starts to delete them.

So, when we log a message, we’ll navigate to the storage and be able to find them in the directory defined above with the filename laravel-YYYY-MM-DD.log.

The Logging Facade

Now your logs are configured and ready to be used. In order to write to the logs, we’re going to use the Log facade. A facade in Laravel is a static-like interface used to call classes within the framework that are available from the service container. Facades provide a more expressive and readable way for developers to use methods while allowing the underlying classes to be as testable and flexible as possible.

All of the facades in Laravel are available in the Illuminate\Support\Facades namespace, so to use the Log facade, you’ll need to include the following use statement at the top of the PHP file you’ll log from.

For our example, I’m going to use the routes/web.php file to be able to add logging to my routes. After the opening PHP tag, add the following:

use Illuminate\Support\Facades\Log;

Once imported, you can use the facade to log an event at any of the levels mentioned above:

Route::get('/', function () { Log::info('This is an info message that someone has arrived at the welcome page.'); return view('welcome'); });

You can place these log statements anywhere, and they can serve as a helpful tool to accurately understand what’s working (or not working) in your application.

[2019-05-04 14:21:52] production.INFO: This is an info message that someone has arrived at the welcome page.

As you can see, the log message begins with the timestamp. Following this is the application environment, which the APP_ENV key defines in the .env file. After that, there’s the level of the log message, followed by the message itself.

Logging to a Particular Channel

Sometimes it may be necessary to bypass the default channel and send a message to a specific channel. The Log facade makes that really straightforward:

Log::channel('slack')->info('This is an informative Slack message.');

This would log to Slack with a level of info.

Now, what if you wanted to create a multi-channel stack on the fly? It’s possible to declare this in a really expressive way, as follows:

Log::stack(['single', 'email'])->critical('I need ice-cream!');

You can pass the array of channels to the stack command and chain the log message with the required level.

Sending Contextual Information

A log message on its own may not be very useful, which is why we can also pass contextual information along with the message. This is passed as an array along with the message, and it’ll be formatted and added to the log message.

Log::alert('This page was loaded', ['user' => 3, 'previous_page' => 'www.google.com']);

This will produce a log message that will give you more information to work out the root cause of any potential problems that may be lying within your application. If you have a theory about what might be causing the problem, then you can use logs to gather some evidence and to help you fix it. You can see that demonstrated here:

[2019-05-03 13:21:58] testing.ALERT: This page was loaded {"user":3,"previous_page":"www.google.com"}

Formatting Log Messages

Monolog provides lots of different ways to be able to format your log messages. I’ve left this until the end because it’s not as critical as the other functionality that we’ve discussed so far. The default formatter is the LineFormatter, which in general does a great job of providing readable and helpful messages. If you’d like something more custom, that’s also very possible.

The Monolog documentation gives a full list of the formatters available, ordered roughly in order of use. This is a great jumping off point if you want to make changes to how your log messages look. You can then pass the formatter key and formatter_with key in the configuration array as you define a given channel.

Here’s how you might configure the daily driver to use the HtmlFormatter:

return [ ... 'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', 'days' => 14, 'formatter' => MonologFormatterHtmlFormatter::class, 'formatter_with' => [ 'dateFormat' => 'Y-m-d', ], ], ... ];

Conclusion

For a starter’s Laravel logging guide, it feels like we’ve covered a lot. We explored in depth how to configure logs and how to send messages to different channels. Plus, we even briefly dipped into how to format and understand those logs.

As I mentioned before, the Laravel documentation is very helpful and readable. I’m always finding my way back to reread how to do something. Also, the source code itself is a really helpful source of learning. Feel free to open up the Log facade file and to explore what you find. As you pull on the threads of the code, you will find your understanding deepen and grow.

Lastly, the community of developers around Laravel is incredibly helpful. Reach out and ask for help—we’re all learning!

Good luck with implementing logs in your own projects, using them to speed up your development, understand your problems quickly, and make awesome things!

This post was written by Kevin Cunningham. Kevin is a full-stack developer working with PHP and Python on the backend and Vanilla JS and Vue on the front end. He loves taking ideas and making something tangible from them that adds value to businesses and lives. He spent 12 years teaching high school mathematics and still loves doing puzzles when he’s not hanging out with his wife and sons on the beach in Brighton, England.

via Laravel News Links
Getting started quickly with logging in Laravel

Laravel Auth: After-Registration Redirect to Previous (Intended) Page

Laravel Auth features a function to redirect logged-in user to the same page they were visiting before. So, for example, if you visit /posts, you get automatically redirected to /login and then enter your data successfully, Laravel will “remember” and redirect you back to /posts instead of default /home. But it doesn’t work with new user registration, let’s see how we can change it.

Imagine the scenario:

  • You visit /posts URL;
  • System uses ‘auth’ middleware and redirects you back to /login form;
  • But you don’t have a user yet, so you click Register and land on /register URL;
  • And then, after successful registration – you get redirected where? To default /home URL, or whatever is specified in $redirectTo property in RegisterController.

So, how to customize it and make Laravel “remember” previous page for registration, too? We will dive into how Auth works internally.

In fact, it already stores that information, we just need to use it.

If you dig deeper into the LoginController logic, it uses Trait AuthenticatesUsers.php from core Laravel’s /vendor folder. And it has this method:

public function login(Request $request) { // ... if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // ... }

Let’s dig deeper – what is sendLoginResponse()? Within the same Trait:

protected function sendLoginResponse(Request $request) { // ... return $this->authenticated($request, $this->guard()->user()) ?: redirect()->intended($this->redirectPath()); }

As you can see, it uses redirect()->intended() method. How does it work? Official Laravel documentation describes it like this:

The intended method on the redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware.

Under the hood, its logic is in /vendor/laravel/framework/src/Illuminate/Routing/Redirector.php:

public function intended($default = '/', $status = 302, $headers = [], $secure = null) { $path = $this->session->pull('url.intended', $default); return $this->to($path, $status, $headers, $secure); } 

Now, let’s take a look at app/Http/Controllers/Auth/RegisterController.php, it also uses a Trait from the core:

trait RegistersUsers { use RedirectsUsers; // ... public function register(Request $request) { $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect($this->redirectPath()); } 

Look at the last part of redirection. As you can see, it uses simple redirect(), without intended(). So this is the part we need to change.

But we can’t edit that directly in /vendor folder, what we do is we copy-paste the same Trait’s method into RegisterController, and change the redirection part:

class RegisterController extends Controller { use RegistersUsers; // ... /** * Handle a registration request for the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function register(Request $request) { $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect()->intended($this->redirectPath()); } }

And, that’s it – now, after registration user will be redirected to the page they were visiting before ‘auth’ middleware restricted their access.

You can read more Auth “tricks” in these articles:

via Laravel News Links
Laravel Auth: After-Registration Redirect to Previous (Intended) Page

How Bowling Balls Are Made

How Bowling Balls Are Made

Link

We recently saw what the insides of a bowling ball looked like. Now see those balls get that way in this clip from How It’s Made, starting out with a soupy goo for its core, wrapped in polymer and polyurethane layers, and then sanded. We were most surprised by the odd shape of the core.

via The Awesomer
How Bowling Balls Are Made

Laravel Auth: After-Registration Redirect to Previous (Intended) Page

Laravel Auth features a function to redirect logged-in user to the same page they were visiting before. So, for example, if you visit /posts, you get automatically redirected to /login and then enter your data successfully, Laravel will “remember” and redirect you back to /posts instead of default /home. But it doesn’t work with new user registration, let’s see how we can change it.

Imagine the scenario:

  • You visit /posts URL;
  • System uses ‘auth’ middleware and redirects you back to /login form;
  • But you don’t have a user yet, so you click Register and land on /register URL;
  • And then, after successful registration – you get redirected where? To default /home URL, or whatever is specified in $redirectTo property in RegisterController.

So, how to customize it and make Laravel “remember” previous page for registration, too? We will dive into how Auth works internally.

In fact, it already stores that information, we just need to use it.

If you dig deeper into the LoginController logic, it uses Trait AuthenticatesUsers.php from core Laravel’s /vendor folder. And it has this method:

public function login(Request $request) { // ... if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // ... }

Let’s dig deeper – what is sendLoginResponse()? Within the same Trait:

protected function sendLoginResponse(Request $request) { // ... return $this->authenticated($request, $this->guard()->user()) ?: redirect()->intended($this->redirectPath()); }

As you can see, it uses redirect()->intended() method. How does it work? Official Laravel documentation describes it like this:

The intended method on the redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware.

Under the hood, its logic is in /vendor/laravel/framework/src/Illuminate/Routing/Redirector.php:

public function intended($default = '/', $status = 302, $headers = [], $secure = null) { $path = $this->session->pull('url.intended', $default); return $this->to($path, $status, $headers, $secure); } 

Now, let’s take a look at app/Http/Controllers/Auth/RegisterController.php, it also uses a Trait from the core:

trait RegistersUsers { use RedirectsUsers; // ... public function register(Request $request) { $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect($this->redirectPath()); } 

Look at the last part of redirection. As you can see, it uses simple redirect(), without intended(). So this is the part we need to change.

But we can’t edit that directly in /vendor folder, what we do is we copy-paste the same Trait’s method into RegisterController, and change the redirection part:

class RegisterController extends Controller { use RegistersUsers; // ... /** * Handle a registration request for the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function register(Request $request) { $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect()->intended($this->redirectPath()); } }

And, that’s it – now, after registration user will be redirected to the page they were visiting before ‘auth’ middleware restricted their access.

You can read more Auth “tricks” in these articles:

via Laravel Daily
Laravel Auth: After-Registration Redirect to Previous (Intended) Page

PHP Implode Example | PHP implode() Function Tutorial

PHP implode() Function Example

PHP Implode Example | PHP implode() Function Tutorial is today’s topic. The implode function in PHP is used to join the elements of an array with a string. The implode() function returns the string from the elements of the array. The function is binary-safe. The implode() function returns a string containing the string representation of all the array items in the same order, with a glue string between each element. We join the array elements with the string. Just like join() function, implode() function also returns the string formed from the elements of the array.

PHP Implode Example

If we have an array of elements, we can use the implode() function to join them all to form one string. See the syntax of PHP implode() function.

Syntax

implode(separator,array)

The separator parameter is optional and specifies what to put between the array elements.

The array parameter is required, and it is the array to join to the string.

See the following example.

<?php

// app.php

$frontend = ['Svelete','Angular','React', 'Vue'];
echo implode("|", $frontend);

See the below output.

PHP Implode Example

 

The implode() function accept its parameters in either order. However, for consistency with the explode() function, you should use the documented order of arguments.

One thing you can note that an array with one or no elements works fine. For example, see the code.

<?php

// app.php

$arrA = ["Asylum","House","Coven"];
$arrB = ["AHS"];
$arrC = [];

echo implode("|", $arrA)."\n";
echo implode("|", $arrB)."\n";
echo implode("|", $arrC);

See the below output.

PHP implode() Function Tutorial

 

The implode() function in PHP is easily remembered as “array to a string,” which means that it takes an array and returns a string. It rejoins any array elements and returns the resulting string, which may be put in a variable.

PHP implode() function on Associative Arrays

The implode function acts on array “values,” disregarding any keys. See the following example.

<?php

// app.php

$devs = ['1st' => 'CloudArchitecht',
        '2nd' => 'DevOps',
        '3rd' => 'DataScientists'];

echo implode(" | ", $devs)."\n";

See the below output.

PHP implode() function on Associative Arrays

 

The implode() function also be used for building tags or complex lists, like the following.

<?php

$elements = array('a', 'b', 'c');

echo "<ul><li>" . implode("</li><li>", $elements) . "</li></ul>";

Also, it is quite handy in INSERT statements.

<?php

 // array containing data
 $array = array(
  "name" => "Krunal",
  "surname" => "Lathiya",
  "email" => "krunal@appdividend.com"
);

// build query...
$sql  = "INSERT INTO table";

// implode keys of $array...
$sql .= " (`".implode("`, `", array_keys($array))."`)";

// implode values of $array...
$sql .= " VALUES ('".implode("', '", $array)."') ";

// execute query...
$result = mysql_query($sql) or die(mysql_error());

If you want to implode the array of booleans, you will get strange result. See the following code.

<?php

// app.php

var_dump(implode('', array(false, true, false, false, true)));

The output is following.

PHP Implode Example Tutorial

 

It is worth noting that if you call implode on the string rather than the array, you do not get your string back, you get NULL.

The implode() function returns a string

 

The null values are imploded too. You can use an array_filter() to sort out the null values.

<?php

$ar = array("krunal", null, "lathiya");

print(implode(',', array_filter($ar, function($v){ return $v !== null; })));

Finally, PHP Implode Example | PHP implode() Function Tutorial is over.

The post PHP Implode Example | PHP implode() Function Tutorial appeared first on AppDividend.

via Planet MySQL
PHP Implode Example | PHP implode() Function Tutorial

PHP Insights

PHP Insights

PHP Insights is a package by Nuno Maduro for instant PHP quality checks in your console.

As found in the project readme file, PHP Insights main features include:

  • Analysis of code quality and coding style
  • Beautiful overview of code architecture and it’s complexity
  • Designed to work out-of-the-box with Laravel, Symfony, and more
  • Contains built-in checks for making code reliable, loosely coupled, simple, and clean
  • Friendly console interface build on top of PHPCS, PHPLOC, and EasyCodingStandard

If you want to use PHP Insights on a Laravel project, an artisan command is provided to run insights:

php artisan insights [-v] 

When you run the command, you are provided an overview insights score spanning code, complexity, architecture, and miscellaneous (i.e., coding style and security). Below the overview is an interactive prompt to go over each scoring area in more detail:

I took PHP Insights for a test drive and was impressed with the ease of setup and use within a Laravel project, and the code is well structured to support any PHP project you might encounter now or in the future.

The project is under active development; the Readme highlights a few ways you can contribute to this project: writing custom Insights from scratch, adding a new insight from PHP CS Sniff, and creating or improving a preset of your favorite framework (here’s the Laravel preset).

At the time of writing, framework presets exist for Laravel, Symfony, and Yii.

Be sure to check out the How to Contribute section of the Readme for examples and details on how you can support this excellent open-source package.

You can learn more about this package, get full installation instructions, and view the source code on GitHub at nunomaduro/phpinsights.


Filed in: News


Enjoy this? Get Laravel News delivered straight to your inbox every Sunday.

No Spam, ever. We’ll never share your email address and you can opt out at any time.

via Laravel News
PHP Insights

The Laravel Security Checklist (Sponsor)

The Laravel Security Checklist (Sponsor)

At Sqreen, we’re on a mission to help developers build more secure applications. But security is hard. It’s not always obvious what needs doing, and the payoffs of good security are at best obscure. Who is surprised when it falls off our priority lists? We’d like to offer a little help.

We created a Laravel Security Checklist to provide some guidance and to cover the best practices on securing your Laravel applications. Here are 10 tips from the checklist to get you started: 

Code

  Filter and Validate All Data

Laravel’s Eloquent ORM uses PDO parameter binding to limit SQL injections. But Laravel also offers other ways to craft SQL queries. Regardless of where the data comes from, whether that’s a configuration file, server environment, GET and POST, or anywhere else, do not trust it. Filter and validate it!

Read more:

  Invalidate Sessions When Required

After any significant application state change, such as a password change, password update, or security errors, expire and destroy the session.

Read more:

  Store Passwords Using Strong Hashing Functions

Ensure that all passwords and other potentially sensitive data are hashed, using robust hashing functions such as bcrypt. Don’t use weak hashing functions, such as MD5 and SHA1. Laravel comes with a native hash mechanism using Bcrypt and Argon2. Use them!

Read more:

  Use Laravel’s built-in encryption

Laravel comes with a built-in encryption mechanism and we highly recommend you use that one instead of building your own. As of PHP 7.2, older encryption libraries have been deprecated, such as Mcrypt. However, PHP 7.2 supports the far better Libsodium library instead. If you want to use a different encryption library, take a look at Libsodium.

Read more:

Infrastructure

  Check Your SSL / TLS Configurations

Ensure that your server’s SSL/TLS configuration is up to date and correctly configured, and isn’t using weak ciphers, outdated versions of TLS, valid security certificates without weak keys, etc, by scanning it regularly.

Read more:

  Rate Limit Requests to Prevent DDoS Attacks

To stop users attempting to perform brute force login attacks and overwhelm your forms, use tools such as Fail2Ban to throttle requests to acceptable levels.

Read more:

  Log All The Things

Regardless of whether you’re logging failed login attempts, password resets, or debugging information, make sure that you’re logging, and with an easy to use, and mature package, such as Monolog.

Read more:

Protection

  Send All Available Security Headers

There are several security headers that you can use to make your websites and web-based applications more secure, for minimal effort. These include HSTS, X-XSS-Protection, X-Frame-Options, X-Content-Type-Options, and a Content Security Policy. Ensure that they’re being configured correctly and sent in your request responses.

Read more:

  Have a Content Security Policy

Whether you have a one page, static website, a large static website, or a sophisticated web-based application, implement a Content Security Policy (CSP). It helps to mitigate a range of common attack vectors, such as XSS.

Read more:

  Monitor your application security

Monitor your application security for suspicious behaviors and attacks. Knowing when your application is starting to get attacked is key to protect it before it’s too late.

Want to read the full checklist? Download your copy here!


Many thanks to Sqreen for sponsoring Laravel News this week.


Filed in: Sponsor


Enjoy this? Get Laravel News delivered straight to your inbox every Sunday.

No Spam, ever. We’ll never share your email address and you can opt out at any time.

via Laravel News
The Laravel Security Checklist (Sponsor)

Dealmaster: There’s a bunch of deals on Anker charging gear today

Today seems like a decent day to stock up on charging gear.
Enlarge /

Today seems like a decent day to stock up on charging gear.

Anker

Greetings, Arsians! The Dealmaster is back a bit earlier than usual this week to highlight a one-day sale that may be of interest to those in need of new charging gear. Amazon is currently discounting a number of wall chargers, battery packs, and charging cables from popular accessories maker Anker as part of its daily “Gold Box” discounts.

Anker runs these kind of peripheral deals frequently, often through discount codes, but most of what’s on sale here is at or near its lowest price to date. Here’s a quick rundown of the highlights:

  • The PowerPort Speed+ Duo wall charger is down to $19.49 from its usual $26. It comes with a 30W USB-C Power Delivery port, which is powerful enough to charge most new smartphones at max speed (with the appropriate cable) and can charge some ultra-thin laptops like Apple’s 12-inch MacBook. There’s a 12W USB-A port alongside that.
  • The black model of the PowerPort I desktop charger is down to $35 from its usual $50. This charger is more designed to live on a desk, but it also includes a 30W USB-C PD port along with four 12W USB-A ports. The whole things gets up to a maximum of 60W, so you won’t be able to get a full-speed charge from every port if you use them all at once. But at this price, it should still be versatile enough to be useful if you regularly have multiple devices to refill at once.
  • If you need new charging cords, a two-pack of the company’s MFi-certified Lightning cables is $15 instead of their usual $20, a three-pack of microUSB cables is $7.70 instead of their usual $11, and its braided USB-C cable is $9.50 instead of its usual $15. The first two items come with an 18-month warranty, while the USB-C cable comes with a lifetime warranty.

There are a few more deals beyond that, but these additional sales aren’t quite as enticing as the ones above. A pair of wireless chargers—one

a flat pad

, the other

a charging stand

—is similarly priced near all-time lows, but

we found the former to be outclassed

by a

competing pad from RAVPower

that is currently available for the same price and the latter maxes out at a slow 5W of power. Neither come with an AC adapter, either. If you can put up with the generally slower speeds of wireless charging as a whole, we think you can do better by paying up a little bit more.

Likewise, a trio of Anker’s power banks are also on sale: a 10,000mAh pack that’s $10 off at $26, a 15,600mAh pack that’s $12 off at $27.19, and a 20,000mAh pack that’s $18 off at $42. All of these are fine: they’re well-reviewed, reliable, and include 18-month warranties. If you’re just looking for a good chunk of capacity at a low price, they should do the job. But they all only have USB-A and microUSB ports. With more and more devices launching with support for USB-C fast charging, we’d prefer our next power bank to be a little more future-proof and include a USB-C PD port.

Per usual with Gold Box sales, all of the deals here will last until the end of the day or until the item in question sells out. Anker is something of a big name in this market for selling reliable accessories for relatively cheap, so if you want to stock up on chargers, you could do worse than some of the deals above. Either way, the Dealmaster will be back tomorrow with a larger deals roundup.

Note: Ars Technica may earn compensation for sales from links on this post through affiliate programs.

via Ars Technica
Dealmaster: There’s a bunch of deals on Anker charging gear today

PHP in 2019

PHP in 2019

Do you remember the popular "PHP: a fractal of bad design" blog post? The first time I read it, I was working in a crappy place with lots of legacy PHP projects. This article got me wondering whether I should just quit and go do something entirely different than programming.

Luckily for me I was able to switch jobs shortly thereafter and, more importantly, PHP managed to evolve quite a bit since the 5.* days. Today I’m addressing the people who are either not programming in PHP anymore, or are stuck in legacy projects.

Spoiler: some things still suck today, just like almost every programming language has its quirks. Many core functions still have their inconsistent method signatures, there are still confusing configuration settings, there are still many developers out there writing crappy code — because they have to, or because they don’t know better.

Today I want to look at the bright side: let’s focus on the things that have changed and ways to write clean and maintainable PHP code. I want to ask you to set aside any prejudice for just a few minutes.

Afterwards you’re free to think exactly the same about PHP as you did before. Though chances are you will be surprised by some of the improvements made to PHP in the last few years.

# TL;DR

  • PHP is actively developed with a new release each year
  • Performance since the PHP 5 era has doubled, if not tripled
  • There’s a extremely active eco system of frameworks, packages and platforms
  • PHP has had lots of new features added to it over the past few years, and the language keeps evolving
  • Tooling like static analysers has matured over the past years, and only keeps growing

Let’s start.

# History summarized

For good measure, let’s quickly review PHP’s release cycle today. We’re at PHP 7.3 now, with 7.4 expected at the end of 2019. PHP 8.0 will be the next version after 7.4.

Ever since the late 5.* era, the core team tries to keep a yearly release cycle, and have succeeded in doing so for the past four years.

In general, every new release is actively supported for two years, and gets one more year of "security fixes only". The goal is to motivate PHP developers to stay up-to-date as much as possible: small upgrades every year are way more easy than making the jump between 5.4 to 7.0, for example.

An active overview of PHP’s timeline can be found here.

Lastly, PHP 5.6 was the latest 5.* release, with 7.0 being the next one. If you want to know what happened to PHP 6, you can listen to the PHP Roundtable podcast.

With that out of the way, let’s debunk some common misconceptions about modern PHP.

# PHP’s performance

Back in the 5.* days, PHP’s performance was… average at best. With 7.0 though, big pieces of PHP’s core were rewritten from the ground up, resulting in two or three times performance increases.

Words don’t suffice though. Let’s look at benchmarks. Luckily other people have spent lots of time in benchmarking PHP performance. I find that Kinsta has a good updated list.

Ever since the 7.0 upgrade, performance only increased. So much that PHP web applications have comparable — in some cases better — performance than web frameworks in other languages. Take a look at this extensive benchmark suite.

Sure PHP frameworks won’t outperform C and Rust, but they do quite a lot better than Rails or Django, and are comparable to ExpressJS.

# Frameworks and ecosystem

Speaking of frameworks: PHP isn’t just WordPress anymore. Let me tell you something as a professional PHP developer: WordPress isn’t in any way representative of the contemporary ecosystem.

In general there are two major web application frameworks, and a few smaller ones: Symfony and Laravel. Sure there’s also Zend, Yii, Cake, Code Igniter etc. — but if you want to know what modern PHP development looks like, you’re good with one of these two.

Both frameworks have a large ecosystem of packages and products. Ranging from admin panels and CRMs to standalone packages, CI to profilers, numerous services like web sockets servers, queuing managers, payment integrations; honestly there’s too much to list.

These frameworks are meant for actual development though. If you’re in need of pure content management, platforms like WordPress and CraftCMS are only improving more and more.

One way to measure the current state of PHP’s ecosystem is to look at Packagist, the main package repository for PHP. It has seen exponential growth. With ±25 million downloads a day, it’s fair to say that the PHP ecosystem isn’t the small underdog it used to be.

Take a look at this graph, listing the amount of packages and versions over time. It can also be found on the Packagist website.

Besides application frameworks and CMSs, we’ve also seen the rise of asynchronous frameworks the past years.

These are frameworks and servers, written in PHP or other languages, that allow users to run truly asynchronous PHP. A few examples include Swoole, Amp and ReactPHP.

Since we’ve ventured into the async world, stuff like web sockets and applications with lots of IO have become actually relevant in the PHP world.

There has also been talk on the internals mailing list — the place where core developers discuss the development of the language — to add libuv to the core. For those unaware of libuv: it’s the same library Node.js uses to allow all its asynchronicity.

# The language itself

While async and await are not available yet, lots of improvements to the language itself have been made over the past years. Here’s a non-exhaustive list of new features in PHP:

While we’re on the topic of language features, let’s also talk about the process of how the language is developed today. There’s an active core team of volunteers who move the language forward, though the community is allowed to propose RFCs.

Next, these RFCs are discussed on the "internals" mailing list, which can also be read online. Before a new language feature is added, there must be a vote. Only RFC with at least a 2/3 majority are allowed in the core.

There are probably around 100 people allowed to vote, though you’re not required to vote on each RFC. Members of the core team are of course allowed to vote, they have to maintain the code base. Besides them, there’s a group of people who have been individually picked from the PHP community. These people include maintainers of the PHP docs, contributors to the PHP project as a whole, and prominent developers in the PHP community.

While most of core development is done on a voluntary basis, one of the core PHP developers, Nikita Popov, has recently been employed by JetBrains to work on the language full time. Another example is the Linux foundation who recently decided to invest into Zend framework. Employments and acquisitions like these ensure stability for the future development of PHP.

Besides the core itself, we’ve seen an increase in tools around it the past few years. What comes to mind are static analysers like Psalm, created by Vimeo; Phan and PHPStan.

These tools will statically analyse your PHP code and report any type errors, possible bugs etc. In some way, the functionality they provide can be compared to TypeScript, though for now the language isn’t transpiled, so no custom syntax is allowed.

Even though that means we need to rely on docblocks, Rasmus Lerdorf, the original creator of PHP, did mention the idea of adding a static analysis engine to the core. While there would be lots of potential, it is a huge undertaking.

Speaking of transpiling, and inspired by the JavaScript community; there have been efforts to extend PHPs syntax in user land. A project called Pre does exactly that: allow new PHP syntax which is transpiled to normal PHP code.

While the idea has proven itself in the JavaScript world, it could only work in PHP if proper IDE- and static analysis support was provided. It’s a very interesting idea, but has to grow before being able to call it "mainstream".

# In closing

All that being said, feel free to still think of PHP as a crappy language. While the language definitely has its drawbacks and 20 years of legacy to carry with it; I can say in confidence that I enjoy working with it.

In my experience, I’m able to create reliable, maintainable and quality software. The clients I work for are happy with the end result, as am I.

While it’s still possible to do lots of messed up things with PHP, I’d say it’s a great choice for web development if used wise and correct.

Don’t you agree? Let me know why! You can reach me via Twitter or e-mail.

via Laravel News Links
PHP in 2019

Wrenching Hero Installs $120 Lawnmower Engine Into Dodge Ram Pickup

The only gasoline internal combustion engines that most people have in their households are either in cars or lawnmowers. That naturally leads to the thought: What if you took the tiny mower motor and installed it into an automobile? That’s what one young intrepid YouTuber did, and the results are glorious.

My coworker Jason Torchinsky and I have been talking about installing a pull-start lawnmower engine into a car for years now, but it looks like YouTuber Carson Duba has beaten us to the punch. And he appears to have done quite a nice job:

What we’re looking at here is an early 1980s Dodge Ram 50 powered by a 6.5 horsepower, 8.1 ft-lb overhead-valve single-cylinder engine sold at Harbor Freight for $120. The tool store, you will be surprised to know, does not actually list “automobile” as an application for this motor. Here’s the full list from the store’s website:

pressure washers, cement mixers, compressors, mowers, log splitters, vacuums, tillers, water pumps, chipper/shredders, generators, blowers

The Dodge had apparently been sitting in the young wrencher’s friend’s yard for a while, so the friend just gave it away. Carson Duba decided to have some fun with it, stripping out the old motor, leaving not much more than the steering intermediate shaft and brake master cylinder. He then built a platform that ties into the original engine mounts, and that carries the single-cylinder engine.

That engine, which can slide on the platform thanks to slotted holes, has a centrifugal clutch on its output shaft, which sends power to a five-speed manual transmission via a sprocket and a chain. To get a 60-tooth sprocket on the transmission end, the YouTuber welded a shaft to the transmission input shaft (unsurprisingly, it was difficult to weld it perfectly straight), and then made a bracket so that the shaft could ride on a bearing (this bracket ties into a custom mount that holds up the front of the transmission). The big sprocket sits on the end of that shaft, and the tension of its chain is set by sliding the motor along the slotted holes in the platform.

The whole build is far more elegant than I expected for something as silly as a lawnmower in a junky old truck. The choke is hooked up to a nice slider on the dash, the original cable running from the gas pedal actuates the tiny engine’s throttle, and there’s a fairly nicely-packaged pull cord that goes through the fender, with a handle in the wheel housing that starts motor. A simple kill switch on the dash cuts it off.

The young mechanic even made his own door panels using material from a shower, and he demonstrates in the video that the truck works in both reverse and in a forward gear, even if it only drives about 20 MPH.

h/t: Kyle!

via Gizmodo
Wrenching Hero Installs $120 Lawnmower Engine Into Dodge Ram Pickup