技術情報

Compressing images for your website

Sometimes, we have to deal with large size images in our website that cause the loading time longer. We need to manage that issue by compressing the images to a smaller without affecting largely the image resolution on the other hand.

Furthermore, we can use lazy loading to load our images on the website apart from compressing images. Firstly I will guide to some websites which provide multiple images’ compression and talk about lazy loading.

Jpeg Compression

As for the jpg and jpeg images compression, you can go to this website which allows only jpg formats images for compression that is available up to 20 images per time. After compression work, there will be a zip file of your compressed images.

Jpg & Png Compression

You have png files instead of jpg, you can use this website which allows not only jpg but also png for compression. The limitation is 20 like above one and there is one more limitation of image size 5MB. After compression work, there will also be a zip file of your compressed images.

Lazy Loading

Image lazy loading means loading images to websites asynchronously, that is, after the content in the top half of the page is fully loaded, or even conditionally, only when they appear in the browser’s viewport. This means that if users don’t scroll all the way down, the images at the bottom of the page won’t even load.

There are many types of lazy loading but I will talk about native browser lazy loading but you can also use other third parties JavaScript libraries.

<img loading = lazy> is compatible with the most popular Chromium-powered browsers (Chrome, Edge, Opera) and Firefox. WebKit (Safari) implementation is in progress. caniuse.com has detailed information on cross-browser compatibility. Browsers that don’t support the loading attribute just ignore it with no side effects.

As I said above, you are welcome to use other libraries like Lozad.js or Intersection_Observer_API also.

Yuuma



Laravel Session

Sessions provide a way to store information about the user across multiple requests. Session configuration file is stored at config/session.php. Laravel provide various drivers like file, cookie, database, mechace / redis, dynamodb, array. By default, Laravel is configured to use file session driver.

Interaction with the Session

Retrieving Data

There are two primary ways to access the session data in laravel: the global session helper and via a Request instance. 

To access the session data via HTTP Request, we can use the get() method, which will take one argument, key to get the session data.

$request->session()->get('key');

When we retrieve an item from the session, we may also pass a default value as the second argument to the get method.

$request->session()->get('key', 'default');

To retrieve all the data in the session, we may use the all method:

$data = $request->session()->all();

To determine if an item is present in the session, we may use the has method:

if ($request->session()->has('users')) {
    //
}

Pushing To Array Session Value

The push method may use to push a new value onto a session value that is an array.

$request->session()->push('user.teams', 'developers');

Retrieving & Deleting An Item

The pull method may used to retrieve and delete an item form the session in a single statement:

$value = $request->session()->pull('key', 'default');

If session data contains an integer we may wish to increment or decrement, we may use the increment and decrement methods.

$request->session()->increment('count');
$request->session()->decrement('count');

We may wish to store in the session for the next request. We may use the flash method.

$request->session()->flash('status', 'Task was successful!');

To remove a piece of data from the session. We may use forget method.

$request->session()->forget('name');

We may wish to remove multiple keys:

$request->session()->forget(['name', 'status']);

The Global Session Helper

You may also use the global session PHP function to retrieve and store data in the session.

Route::get('/home', function () {
// Retrieve a piece of data from the session...
  $value = session('key');

// Specifying a default value...
  $value = session('key', 'default');

// Store a piece of data in the session...
  session(['key' => 'value']);
});

By Ami



Local Storage Issues

We use LocalStorage often in our web application to store data. But there are still some issues relating with local storage and you should consider a few facts before using this.

LocalStorage is a web storage object for storing data on the client, or local, or user’s computer. Locally stored data has no expiration date and remains until it is deleted. Local storage has caught the attention of developers as a lightweight solution for storing data that does not include databases or even a server.

But there are some down sides also to consider.

XSS vulnerabilities

Local storage has many similarities with cookies, including the same security risks. One of them makes it easy to do site scripting, which by stealing cookies allows a user to create a login session for a site. Storing something sensitive, such as a password, in a local storage file makes the process really easier for a hacker; Because they do not need to put cookies in their own browser.

Less Control

With local storage, there is no server-side storage or database that the developer can control. This can be a problem for several reasons. One is that once the code or information is saved, there is no way for the developer to update the code or information. The user has to delete the file manually and has to find the file. Alternatively, you need to clear your browser’s cache to lose all the stored data.

User might clear the storage

Clearing your browser’s cache on a regular basis will help browsers work more effectively. This is usually the first step you should take when troubleshooting browser issues such as pages not loading properly. This is a problem when using local storage to support the functionality of your site. When the user clears the browser cache, that information is completely lost.

As an alternative to local storage, there are several ways to handle this. For example – server side sessions, DB, and third party storage services etc.

Yuuma



Laravel Service-Repository Pattern

In this article, you’ll learn about:
• Main benefits of using Repository Pattern
• How to implement a PHP Repository Pattern in Laravel?
• We will show you how to start code and implement it in the Laravel based App.

What Important – Why we need a design pattern?

Service-Repository design pattern is clean and sustainable. The concept of repositories and services ensures that you write reusable code and helps to keep your controller as simple as possible making them more readable.

The main idea to use Repository Pattern in a Laravel application is to create a bridge between models and controllers. In other words, to decouple the hard dependencies of models from the controllers.

Repositories are usually a common wrapper for your model and the place where you would write different queries in your database. A service on the other hand is a layer for handling all your application’s logic.

Based on experience, it’s really conducive to separate the logic and the wrapper of the model especially when you’re working on team or big projects.

The use of Repository Pattern has many benefits, below is a list of the most important ones:
• It centralizes data logic or business logic and service logic.
• It gives a substitution point for the unit tests.
• Provides a flexible architecture.
• Reduces duplication of code
• A lower chance for making programming errors.

Let’s start with code and implement it in your Laravel app!

Now you know the benefits of the repository pattern in Laravel, so let’s implement them in your application! 

Repository

In the beginning, we will start with a folder structure. Laravel does not have a repository command. You have to do it manually. We should start by creating a Repositories folder into our app folder. Then add PostRepository file. So the final file structure should look like this:

-- app
---- Repositories
--------PostRepository.php

We call the Post model in the constructor of our class. So the PostRepository class will look like this:

<?php

namespace App\Repositories;

use App\Models\Post;

class PostRepository
{
    /**
     * @var Post
     */
    protected $post;

    /**
     * PostRepository constructor.
     *
     * @param Post $post
     */
    public function __construct(Post $post)
    {
        $this->post = $post;
    }

    /**
     * Get all posts.
     *
     * @return Post $post
     */
    public function getAll()
    {
        return $this->post
            ->get();
    }

    /**
     * Get post by id
     *
     * @param $id
     * @return mixed
     */
    public function getById($id)
    {
        return $this->post
            ->where('id', $id)
            ->get();
    }

    /**
     * Save Post
     *
     * @param $data
     * @return Post
     */
    public function save($data)
    {
        $post = new $this->post;

        $post->title = $data['title'];
        $post->description = $data['description'];

        $post->save();

        return $post->fresh();
    }

    /**
     * Update Post
     *
     * @param $data
     * @return Post
     */
    public function update($data, $id)
    {
        
        $post = $this->post->find($id);

        $post->title = $data['title'];
        $post->description = $data['description'];

        $post->update();

        return $post;
    }

    /**
     * Update Post
     *
     * @param $data
     * @return Post
     */
    public function delete($id)
    {
        
        $post = $this->post->find($id);
        $post->delete();

        return $post;
    }

}

Service

Like repository, laravel doesn’t have a service command. We should start by creating a Services folder into our app folder. Then add PostService file. So the final file structure should look like this:

-- app
---- Services
--------PostService.php
<?php

namespace App\Services;

use App\Models\Post;
use App\Repositories\PostRepository;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use InvalidArgumentException;

class PostService
{
    /**
     * @var $postRepository
     */
    protected $postRepository;

    /**
     * PostService constructor.
     *
     * @param PostRepository $postRepository
     */
    public function __construct(PostRepository $postRepository)
    {
        $this->postRepository = $postRepository;
    }

    /**
     * Delete post by id.
     *
     * @param $id
     * @return String
     */
    public function deleteById($id)
    {
        DB::beginTransaction();

        try {
            $post = $this->postRepository->delete($id);

        } catch (Exception $e) {
            DB::rollBack();
            Log::info($e->getMessage());

            throw new InvalidArgumentException('Unable to delete post data');
        }

        DB::commit();

        return $post;

    }

    /**
     * Get all post.
     *
     * @return String
     */
    public function getAll()
    {
        return $this->postRepository->getAll();
    }

    /**
     * Get post by id.
     *
     * @param $id
     * @return String
     */
    public function getById($id)
    {
        return $this->postRepository->getById($id);
    }

    /**
     * Update post data
     * Store to DB if there are no errors.
     *
     * @param array $data
     * @return String
     */
    public function updatePost($data, $id)
    {
        $validator = Validator::make($data, [
            'title' => 'bail|min:2',
            'description' => 'bail|max:255'
        ]);

        if ($validator->fails()) {
            throw new InvalidArgumentException($validator->errors()->first());
        }

        DB::beginTransaction();

        try {
            $post = $this->postRepository->update($data, $id);

        } catch (Exception $e) {
            DB::rollBack();
            Log::info($e->getMessage());

            throw new InvalidArgumentException('Unable to update post data');
        }

        DB::commit();

        return $post;

    }

    /**
     * Validate post data.
     * Store to DB if there are no errors.
     *
     * @param array $data
     * @return String
     */
    public function savePostData($data)
    {
        $validator = Validator::make($data, [
            'title' => 'required',
            'description' => 'required'
        ]);

        if ($validator->fails()) {
            throw new InvalidArgumentException($validator->errors()->first());
        }

        $result = $this->postRepository->save($data);

        return $result;
    }

}

We inject the PostRepository dependency into the constructor of our PostService class. Now that we are done with the repository-service setup. 

PostController -> PostService -> PostRepository

So we can use makinglogic like this in the controller:

<?php

namespace App\Http\Controllers;

use App\Services\PostService;
use Exception;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * @var postService
     */
    protected $postService;

    /**
     * PostController Constructor
     *
     * @param PostService $postService
     *
     */
    public function __construct(PostService $postService)
    {
        $this->postService = $postService;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $result = ['status' => 200];

        try {
            $result['data'] = $this->postService->getAll();
        } catch (Exception $e) {
            $result = [
                'status' => 500,
                'error' => $e->getMessage()
            ];
        }

        return response()->json($result, $result['status']);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = $request->only([
            'title',
            'description',
        ]);

        $result = ['status' => 200];

        try {
            $result['data'] = $this->postService->savePostData($data);
        } catch (Exception $e) {
            $result = [
                'status' => 500,
                'error' => $e->getMessage()
            ];
        }

        return response()->json($result, $result['status']);
    }

    /**
     * Display the specified resource.
     *
     * @param  id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $result = ['status' => 200];

        try {
            $result['data'] = $this->postService->getById($id);
        } catch (Exception $e) {
            $result = [
                'status' => 500,
                'error' => $e->getMessage()
            ];
        }
        return response()->json($result, $result['status']);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  Post $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update post.
     *
     * @param Request $request
     * @param id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $data = $request->only([
            'title',
            'description'
        ]);

        $result = ['status' => 200];

        try {
            $result['data'] = $this->postService->updatePost($data, $id);

        } catch (Exception $e) {
            $result = [
                'status' => 500,
                'error' => $e->getMessage()
            ];
        }

        return response()->json($result, $result['status']);

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $result = ['status' => 200];

        try {
            $result['data'] = $this->postService->deleteById($id);
        } catch (Exception $e) {
            $result = [
                'status' => 500,
                'error' => $e->getMessage()
            ];
        }
        return response()->json($result, $result['status']);
    }
}

That’s it! You have implemented a repository pattern in your app. Now you can add new repositories for the other models you are using in your application.

By Ami



Magic methods in PHP – Part 2

I will continue to talk about magic methods article I wrote last week. For the part 1, you can read here.

ToString

The magic __toString () method allows you to define what you would like to display when an object of the class is treated as a string. If you use echo or print on your object, and you haven’t defined the __toString () method, it will give an error.

<?php
class Student {
    private $name;
 
    public function __construct($name) 
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    public function __toString()
    {
        return 'Name: '.$this->name;
    }
}
 
$student = new Student('Yuuma');
echo $student;
?>

Call

If the __get () and __set () methods are called for non-existent properties, the __call () method is called when trying to invoke inaccessible methods, the methods that have not been defined in your class.

<?php
class Student {
    public function __call($methodName, $arg) 
    {
        // $methodName = getName
        // $arg = array('1')
    }
}
 
$student = new Student();
$student->getName(1);
?>

Isset

The magic __isset () method is called when you call the isset () method on inaccessible or non-existent object properties. Let’s see how it works with an example.

<?php
class Student {
    private $data = array();
 
    public function __isset($name) 
    {
        return isset($this->data[$name]);
    }
}
 
$student = new Student();
echo isset($student->email);
?>

Invoke

The magic __invoke () method is a special method that is called when you try to call an object as if it were a function. the $student object is treated as if it were a function, and since we have defined the __invoke () method, it will be called instead of giving you an error. The main purpose of the __invoke () method is that if you want to treat your objects as callable, you can implement this method.

<?php
class Student {
    private $name;
 
    public function __construct($name) 
    {
        $this->name = $name;
    }
 
    public function __invoke()
    {
        echo 'Invoke function';
    }
}
 
$student = new Student('John');
$student();
?>

There are still some magic methods in PHP but let me stop here as I had written most used methods in article part 1 and part 2. If you are interest for more, you can check it out in PHP official documentation.

Yuuma




アプリ関連ニュース

お問い合わせはこちら

お問い合わせ・ご相談はお電話、またはお問い合わせフォームよりお受け付けいたしております。

tel. 06-6454-8833(平日 10:00~17:00)

お問い合わせフォーム