Category Archives: Laravel

Laravel Copy Tables To Other Server

Recently in one of my Laravel project, I had a situation where some of the tables are required to copy from one db server to other db server on real time basis.

Laravel Observer
Laravel

First of all I thought about using binary logging but it, but my hosting provider refused to enable binary logging. Other option is to use federated storage engine. But hosting provider refused to enable it too. In fact the tech support team asked me a question that what is Fedarated storage engine? So I gave up the hope on them. Finally I implemented with the strategy that I am going to explain in this blog.

Using Laravel Observer and Eloquent

In Laravel we can use model observers to listen to the events on models and take actions. Here are steps you have to perform.

Step 1 : Create Observer

Create a new Class in App\Http\Observers folder and name is ModelObserver

Step 2 : Assign Observer to Model

In your model file add boot function as following.

public static function boot()
{
parent::boot();
YourModelName::observe(new \App\Http\Observers\ModelObserver);
}

Step 3 : Add Methods to Your Observer

In your ModelObserver class add following methods.

public function created($model)
{

}

public function updated($model)
{

}

Now when you insert or update record with Eloquent it will invoke created and updated method and will send model instance as param.

Replication to Other Server

Now next step is to implement replication strategy. For this we are going to create separate model and use remote server connection with that model.

Step 1 : Save Remote Host Connection

For this first of all create saparate MySql connection in your config/database.php file

‘replica’ => [
‘driver’ => ‘mysql’,
‘host’ => env(‘REPLICA_DB_HOST’, ‘remotehost’),
‘port’ => env(‘REPLICA_DB_PORT’, ‘3306’),
‘database’ => env(‘REPLICA_DB_NAME’, ‘your_db’),
‘username’ => env(‘REPLICA_DB_USERNAME’, ‘your_username’),
‘password’ => env(‘REPLICA_DB_PASSWORD’, ‘your_password’),
‘charset’ => ‘utf8’,
‘collation’ => ‘utf8_unicode_ci’,
‘prefix’ => ”,
‘strict’ => false,
‘engine’ => null,
]

Step 2 : Create Model to Connect to Remote Host

Now create a separate model and assign remote server connection to it.

<?php

namespace App\Http\Models;

use Illuminate\Database\Eloquent\Model;

class RemoteModel extends Model
{
protected $connection= ‘replica’;
protected $table = ‘remote_table’;
}

Step 3 : Replicate Model

Now inside your observer’s created method add following code.

if($model instanceOf \App\Http\Models\Model){
$modelArray = $model->toArray();
$newModel = new \App\Http\Models\RemoteModel;
foreach( $modelArray as $key => $value ){
if(gettype($modelArray[$key]) != ‘array’){
$newModel[$key] = $modelArray[$key];
}
}
$newModel->save();
}

As you can see in above code that we are checking first if model created is type of our Model Class and then creating object of RemoteModel and assigning values of Model to RemoteModel object and then finally call save method, this will create row in remote table on remote server.

Lumen Microservice Architecture

I posted a blog on implementing Microservice Architecture. Here is the link. This blog is second part of it. In first post I just explained about Microservices and proposed architecture. In this post I will give practical example of Lumen Microservice.

Microservice Using Laravel

Lumen Microservice

Lumen Microservice

Lumen Microservice

You can either install Lumen in public folder of main Laravel app or you can have different installation all together.

composer global require “laravel/lumen-installer”

After it’s installed, now lets create an API.

$router->post(‘getDetails’,’APIController@getDetails’);
Now in a controller define the API.
public function getDetails(){
      return response()->json(array(
           “key1″=>”value1”,
           “key2″=>”value2”,
           “key3″=>”value3”,
           “key4″=>”value4”,
           “key5″=>”value5”
      ));
}
Now we can call these API either through our JavaScript app as Ajax request or we can call it in Laravel app using GuzzleHttp

Benefits of GuzzleHttp as mentioned on their website

  • Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc…
  • Can send both synchronous and asynchronous requests using the same interface.
  • Uses PSR-7 interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle.
  • Abstracts away the underlying HTTP transport, allowing you to write environment and transport agnostic code; i.e., no hard dependency on cURL, PHP streams, sockets, or non-blocking event loops.
  • Middleware system allows you to augment and compose client behavior.

Install GuzzleHttp

Install it using Composer.

composer require guzzlehttp/guzzle

Once installed we can use in controller by name space.

use GuzzleHttp\Client;
Now call API using this client.

$client = new Client();

$response = $client->post(‘/lumenapi/public/getDetails’, [
‘form_params’ => []
]);

$data = json_decode($response->getBody()->getContents(), true);

Here in above code if you want to pass any param in POST request, you can do so inside form_params.
Above code is for the synchronous request. We can also have async request.
$request = new Request(‘GET’,’/lumenapi/public/getDetails’);
$client->sendAsync($request)->then(function ($response) {
       $data = json_decode($response->getBody()->getContents(), true);
});
So this way we can build Lumen Microservice and consume it with Laravel app.

Laravel Cron Job Monitoring

When we build applications using Laravel, we also have lots of Laravel cron jobs. Once the application is deployed on production server, it’s mandatory to monitor cron jobs. Many time it happens that due to certain issues crons are not executed. That may lead to lot of problems with your customers. As a server admin we can always login to server and check the logs. But what if we have a very simple page where we can see this logs.

Laravel Cron Jobs

Laravel Cron Jobs

Here in this blog I am going to explain a very simple approach to monitoring cron jobs. First of all for each cron jobs we will build a log file.

Build Laravel Cron Log File

We will use Laravel File class to create log files. First of all add to controller.

use File;

Add a variable to have counts of processed records with cron.

$count = 0;

Now inside foreach loop or any other loop you have increase this count.

foreach($records as $record){

$count++;

}

Once the cron execution logic is over build log file.

//Preparing log files on server.
$data = json_encode([“description”=>”Cron Execution Report”,”count”=>$count,”date”=>date(‘Y-m-d H:i:s’)]);
$fileName = ‘cronExecutionReport.json’;
File::put(public_path(‘/logs/’.$fileName),$data);

This way add logs files everywhere in your cron.

Read The Log File and Display It

Now that we have all the log files generated, we just have to read it and display it. Here is the logic for the same.

foreach (glob(public_path(“logs/*.json”)) as $file) {

$json = json_decode(file_get_contents($file), true);

echo ‘<span style=”font-weight:bold;font-size:25px”>’.$json[‘description’].'<br/>’;

print( ‘<span style=”font-weight:normal;font-size:20px”>Total Count : ‘.$json[‘count’].'<br/>’);

print( ‘<span style=”font-weight:normal;font-size:20px”>Last Processed Date : ‘.$json[‘date’].'<br/>’);

}
echo ‘<script type=”text/javascript”>setInterval(function(){window.location.reload()},10000)</script>’;

Add the above code in your controller function so that it will display following output and it will also refresh the page after 10 seconds to get the latest logs from server.

Cron Execution Report
Total Count : 10
Last Processed Date : 2018-11-09 10:56:01

So this way you can build a very simple Laravel Cron Job monitoring page.

Microservice Architecture with Laravel and Lumen

Recently in Google DevFest Ahmedabad I got to learn about Microservice Architecture. So I decided to try and implement with Laravel. In this post I am going to explain about it.

What is Microservice Architecture?

It is a method of developing software applications as a suite of independently deployable, small, modular services in which each service runs a unique process and communicates through a well-defined, lightweight mechanism to serve a business goal.

So as definition suggest, it’s a set of independently deployable services. So how we can implement it with Laravel? Please check the diagram below.

Microservice Architecture

Microservice Architecture

Here first layer is a Laravel application, which act as API gateway. All the front ends call API Gateway URL, all the users are first authorized by API gateway. API gateway then calls respective service which is created in Laravel Lumen.

Gateway has sort of service repository which is nothing but singleton class which includes service metadata and hostnames. Using which it can determine which service to call.Here we are using Laravel Passport to authenticate and call service.

Gateway makes asynchronous requests to microservice which is nothing but API call. We don’t block any user request. Gateway  can also modify the service response if required and also can cache the request to make response faster.

This microservice will then execute and process the call and will return data in JSON format.  Each service is deployed as stand alone instance and have separate host name. The reason for using Lumen for service is it has all the features of Laravel and it’s fast and easy to scale and maintain and it’s ideal for making APIs.

Benefits of mircoservice architecture

There are number of benefits of mircoservice architecture.

Because each service is focused on only a small part they can be more lightweight and much faster performance-wise.

Also since it’s just API calls. It is possible to have different languages for different service. For example there could be notification service made in NodeJs. So it’s not necessary to be only Lumen or Laravel.

Each service can be scaled depending on usage. In short could be a good architecture for large application. In upcoming post I will show you how does this really work with example code.

Beginning Laravel Video Course

Here is something unusual I did apart from programming. My first ever video course “Beginning Laravel” with Packt Publishing

In this course you will learn about basics of Laravel Development. First section is about installation of Laravel. This section will start with introduction of Laravel and installation of Laravel in Mac, Windows and Linux. Then we will cover, basics of Laravel including, understanding of Framework Structure, basics of Artisan Commands, Composer, Core Concepts of Laravel, MVC structure, Database Migrations, Laravel Controllers, Models and Views etc. In last section
We will finish this course by creating simple Web application with Laravel which will have CRUD operations and basic validations in final section, this will help you getting started with Laravel Development. If you are interested in learning Laravel then this is the course you are looking for. You can buy it at following link.

Beginning Laravel Video Course

Hope you will like this course. Let me know your feedback in comments.

Laravel: Failed to connect to 192.241.224.13 port 80 on OSX

Recently I was trying to create new Laravel application with Laravel installer, it was not working and it was throwing following error.

Failed to connect to 192.241.224.13 port 80: Operation timed out [url] http://192.241.224.13/laravel-craft.zip

I was not sure about error so I tried few things like updating composer and updating laravel installer but still it was not working but finally I was able to solve problem so in this blog I am going to explain how to solve this issue.
This issue is because even after updating laravel installer version with composer it’s still using old version of composer which was installed in /usr/local/bin library. To find out this type following command in terminal.
laravel –version
If it shows following output that means you are still using old version of laravel installer.
Laravel Craft version 1.0.0
So to remove this version first of all remove old version. Go to terminal and type following command.
rm /usr/local/bin/laravel
Now will again install laravel with following command.
composer global require “laravel/installer”
It will install laravel in your users home directory, so you have to add path to it in your bash_profile file. Open the bash_profile file for editing.
sudo nano ~/.bash_profile
And copy following line in it.
export PATH=/Users/USERNAME/.composer/vendor/bin:$PATH
In above line replace USERNAME with your OSX username. Save the file and reopen the terminal. Now again type following command.
laravel –version
And it will show following output.
Laravel Installer version 1.3.1
So now you have the latest version of laravel installer, create new laravel application with following command
laravel new app-name
Hope this helps you.

.htaccess Doesn’t Work in Amazon AWS EC2 Instance with Ubuntu

Recently I was configuring Laravel application in Amazon AWS EC2 instance which was having Ubuntu and Apache installed. The problem was htacess file was not working so Laravel routes were not working. Instead of parsing laravel routes it always shows error URL not found.

The problem is by default in apache installed on ubuntu doesn’t have .htaccess enabled so first you have to manually enable it in config file and restart apache.

Here are the steps.

1) Login to your EC2 instance with SSH.

ssh -i “Yourkey.pem” ubuntu@yourpublicip

2) Enable Mode Rewrite, this is just incase if it’s not enabled.

sudo a2enmod rewrite

3) Go to following directory.

cd /etc/apache2/sites-available

If you use LS command here you will see following file.

000-default.conf

That’s the file with default apache configuration which are applied to your sites in /var/www/html folder.

4) Open this file for editing.

sudo nano 000-default.conf

5) Add following lines after DocumentRoot /var/www/html line.

<Directory />
     Options FollowSymLinks
     AllowOverride All
</Directory>
<Directory /var/www/html>
     Options Indexes FollowSymLinks MultiViews
     AllowOverride All
     Order allow,deny
     allow from all
</Directory>

6) Save the file and restart the apache.

sudo service apache2 restart

that’s it and now your .htaccess file will work and your laravel application will start working.

Amazon RDS Connection Limit Exhausted

Recently in one of our project we built laravel application and deployed it on Amazon AWS and database was on Amazon RDS. In start there was no issue but after some months we had problems with database connection. After sometime laravel app could not connect to Amazon RDS.

So I checked RDS and dashboard and found out that number of database connection was beyond allowed limits. It means connection open to RDS was not closed after sometime and there were lots of half opened connections. That eventually crashing RDS sever and then connection was not established till we restart the RDS server.

So next step was to check database queries and find the queries which are taking time to execute and get data. After looking into all the queries I got the query which is taking long time to execute and that query was responsible half closed or non closed database connections and which is ultimately crashing Amazon RDS server.

So how I fixed that. Well we have a only one solution to speed up database queries and that is

INDEXING

Yes, that ‘s right indexing solved my issue. There was a table in my database which has 100K records and executing query from it was taking lots of time as there was no indexing. So I created an index on columns which are used mostly for querying that table and after creating index query was working blazing fast.
If you are facing the same issue, better check your database queries and optimize it with indexing to make it faster.

Laravel 5.x Store Uploaded Files to Amazon S3

Recently in one of my Laravel 5.2 project, we used Amazon s3 to store static files and user uploaded files. So here in this blog I am going to explain how to do this.

1) First of all install following plugin through composer.

composer require league/flysystem-aws-s3-v3 ~1.0

2) Now add your S3 credentials to your environment (.env file)

S3_KEY=YOUR_KEY
S3_SECRET=YOUR_SECRET
S3_REGION=YOUR_REGION
S3_BUCKET=YOUR_BUCKET

3) Open config.filesystems.php and configure s3 driver as follow.

‘s3’ => [
            ‘driver’ => ‘s3’,
            ‘key’    => env(‘S3_KEY’),
            ‘secret’ => env(‘S3_SECRET’),
            ‘region’ => env(‘S3_REGION’),y.
            ‘bucket’ => env(‘S3_BUCKET’),
        ]

4) Now open controller where you have code to manage uploaded file and add following dependency.

use IlluminateContractsFilesystemFilesystem;

5) Use following code to store your file to S3.

$image = $request->file(‘user_uploaded_image’);
$imageFileName = time() . ‘.’ . $image->getClientOriginalExtension();
$s3 = Storage::disk(‘s3’);

$filePath = ‘/mypath’/.$imageFileName;
$s3->put($filePath, file_get_contents($image), ‘public’);
$uploadedFileS3Path = ‘https://’.env(‘S3_BUCKET’).’/’.$filePath;
Please note in my case I configured S3 bucket to be direct URL of uploaded file. In case your case if you have not configured it then your path will be as follow.
$uploadedFileS3Path = ‘http://s3-‘.env(‘S3_REGION’).’.amazonaws.com/’.env(‘S3_BUCKET’).’/’.$filePath;
This path you can use to display file and you can store it to database as well.
Special Case 
If you are using it in localhost using XAMPP in your windows system. You have to do following few steps.
Download certificate pem file from this link. https://curl.haxx.se/ca/cacert.pem and store it to some where in your C drive or whatever drive you have your xampp installed.
For example I put it in  C:codecacert.pem
Now open your php.ini file and bottom of the file add following line.
curl.cainfo = C:codecacert.pem
That’s it and it will work in your local environment too. Hope this helps you.

Laravel 5.3 Run Artisan Command Through Routes

Recently for one my project we installed Laravel 5.3 on shared server where we were not having SSH or route access.

As we know general practice with Laravel is to create database tables with migrations and for that we have to run artisan commands through terminal and SSH.

But in our case we were not having SSH access, we have only FTP and database access so we have to figure out a way to run this commands through web. In this blog I am going to explain how to do this.

After reading Laravel 5.3 document I came to know that Laravel gives you Artisan class to run artisan command. So what I did is I created two routes, one for creating migration and other to run migration.

To create migration

Route::get(‘/create-migration-command’, function () {
    Artisan::call(‘make:migration’, [‘name’ => ‘migration_name’]);
});
As you can see here the command is make:migration and parameter passed is name of migration. 
Virtually it is equivalent to following SSH command.
php artisan make:migration migration_name
This will generate migration file in database folder, you can open it through FTP and add necessary code of migration.

Run Migration

Route::get(‘/run-migration-command’, function () {
    Artisan::call(‘migrate’, []);
});
Virtually it is equivalent to following SSH command.
php artisan migrate
Hope this helps you.