PHP & Web Development Blogs

Showing 36 to 40 of 53 blog articles.
4076 views · 2 years ago

![Iterator in PHP](https://images.ctfassets.net/vzl5fkwyme3u/5I2KRmarVm4Gg0GuYcOeSk/b8c5156475053a19537059c19f244d61/AdobeStock_144145979.jpeg?w=1000)

Every time I see this

```php

$users = [new User(), new User()];

```

I see a lost opportunity to use Iterator.

### Why Iterators?

Collections are an awesome way to organize your previously no-named array. There is a couple of reasons why you should use iterators. One of reason stays for behavior, you can specify exact behavior on standard calls such as next, current, valid etc. Other reason could be that you want to ensure that collection contains an only specific type of an object.

Understand a suffer from using an array of unknown value types.

Very common in the PHP world arrays are used to store all kind of data, in many dimensions in many nested forms. Arrays introduced infinite flexibility to the developer, but because of that, they become very evil.

### Example:

- Your function (getUsers) returns an array of User objects.

- Another function (setUsersToActiveState) using getUsers output array and set all users active status to true.

- setUsersToActiveState loop through the array and expect to call a specific method on array item. For example, the method name is getActiveStatus.

- If given array is an array of desired objects which have a callable method getActiveStatus, all fine. But if not exception will be thrown.

- How we can ensure that given array is always an array of objects of a specific type?

```php

public function getUsers(): array

{

/ **

here happen something which gets users from database

....

**/

return $userArray;

}

public function setUsersToActiveState()

{

$users = $this->getUsers();

/ ** @var User $param */

foreach ($users as $user) {

if(!$user->getActiveStatus()) {

$user->setActiveStatus(true);

}

}

}

```

There immediately two problems occurred.

1. One is the problem of type. Our IDE doesn't know what's inside array of $users, so because of that IDE can't suggest us how to use $user element. (I put this comment block / ** @var User $param */ above foreach, it works for phpStorm and I guess for some other IDEs)

2. Your colleagues! How they possibly know what's inside array if there is no any hint.

3. Bonus problem, getUsers can return literally any array and there won't be warning in the system.

### Solution

```php

/ / Create a collection which accepts only Users

class UsersCollection implements \IteratorAggregate

{

/ ** @var array */

private $users = [];

public function getIterator() : UserIterator

{

return new UserIterator($this);

}

public function getUser($position)

{

if (isset($this->users[$position])) {

return $this->users[$position];

}

return null;

}

public function count() : int

{

return count($this->users);

}

public function addUser(User $users)

{

$this->users[] = $users;

}

}

/ / Create an Iterator for User

class UserIterator implements \Iterator

{

/ ** @var int */

private $position = 0;

/ ** @var UsersCollection */

private $userCollection;

public function __construct(UsersCollection $userCollection)

{

$this->userCollection = $userCollection;

}

public function current() : User

{

return $this->userCollection->getUser($this->position);

}

public function next()

{

$this->position++;

}

public function key() : int

{

return $this->position;

}

public function valid() : bool

{

return !is_null($this->userCollection->getUser($this->position));

}

public function rewind()

{

$this->position = 0;

}

}

```

### Tests

Off course there is the tests to ensure that our Collection and Iterator works like a charm. For this example I using syntax for PHPUnit framework.

```php

class UsersCollectionTest extends TestCase

{

/ **

* @covers UsersCollection

*/

public function testUsersCollectionShouldReturnNullForNotExistingUserPosition()

{

$usersCollection = new UsersCollection();

$this->assertEquals(null, $usersCollection->getUser(1));

}

/ **

* @covers UsersCollection

*/

public function testEmptyUsersCollection()

{

$usersCollection = new UsersCollection();

$this->assertEquals(new UserIterator($usersCollection), $usersCollection->getIterator());

$this->assertEquals(0, $usersCollection->count());

}

/ **

* @covers UsersCollection

*/

public function testUsersCollectionWithUserElements()

{

$usersCollection = new UsersCollection();

$usersCollection->addUser($this->getUserMock());

$usersCollection->addUser($this->getUserMock());

$this->assertEquals(new UserIterator($usersCollection), $usersCollection->getIterator());

$this->assertEquals($this->getUserMock(), $usersCollection->getUser(1));

$this->assertEquals(2, $usersCollection->count());

}

private function getUserMock()

{

/ / returns the mock of User class

}

}

class UserIteratorTest extends MockClass

{

/ **

* @covers UserIterator

*/

public function testCurrent()

{

$iterator = $this->getIterator();

$current = $iterator->current();

$this->assertEquals($this->getUserMock(), $current);

}

/ **

* @covers UserIterator

*/

public function testNext()

{

$iterator = $this->getIterator();

$iterator->next();

$this->assertEquals(1, $iterator->key());

}

/ **

* @covers UserIterator

*/

public function testKey()

{

$iterator = $this->getIterator();

$iterator->next();

$iterator->next();

$this->assertEquals(2, $iterator->key());

}

/ **

* @covers UserIterator

*/

public function testValidIfItemInvalid()

{

$iterator = $this->getIterator();

$iterator->next();

$iterator->next();

$iterator->next();

$this->assertEquals(false, $iterator->valid());

}

/ **

* @covers UserIterator

*/

public function testValidIfItemIsValid()

{

$iterator = $this->getIterator();

$iterator->next();

$this->assertEquals(true, $iterator->valid());

}

/ **

* @covers UserIterator

*/

public function testRewind()

{

$iterator = $this->getIterator();

$iterator->rewind();

$this->assertEquals(0, $iterator->key());

}

private function getIterator() : UserIterator

{

return new UserIterator($this->getCollection());

}

private function getCollection() : UsersCollection

{

$userItems[] = $this->getUserMock();

$userItems[] = $this->getUserMock();

$usersCollection = new UsersCollection();

foreach ($userItems as $user) {

$usersCollection->addUser($user);

}

return $usersCollection;

}

private function getUserMock()

{

/ / returns the mock of User class

}

}

```

### Usage

```php

public function getUsers(): UsersCollection

{

$userCollection = new UsersCollection();

/ **

here happen something which gets users from database

....

**/

foreach ($whatIGetFromDatabase as $user) {

$userCollection->addUser($user);

}

return $userCollection;

}

public fucntion setUsersToActiveState()

{

$users = $this->getUsers();

foreach ($users as $user) {

if(!$user->getActiveStatus()) {

$user->setActiveStatus(true);

}

}

}

```

As you can see setUsersToActiveState remains the same, we only do not need to specify for our IDE or collagues what type $users variable is.

### Extending functionalities

Believe or not you can reuse this two objects and just change names of variables to fit most of the needs. But if you want any more complex functionality, than feel free to add it in iterator or collection.

#### Example 1

For example, let's say that userCollection accepts only users with age more than 18. Implementation will happen in UsersCollection class in the method addUser.

```php

public function addUser(User $users)

{

if ($user->getAge() > 18) {

$this->users[] = $users;

}

}

```

#### Example 2

You need to add bulk users. Then you can expand your userCollection with additional method addUsers and it might look like this.

```php

public function addUsers(array $users)

{

foreach($users as $user) {

$this->addUser(User $users);

}

}

```

6912 views · 2 years ago

![Creating a Tiny Blog Management system in Laravel 5.7](https://images.ctfassets.net/vzl5fkwyme3u/7hiPly9aeW8i6IU0wkK4Gg/5b13c5fb7f273be44f44c87fb2ce5f5f/AdobeStock_205314257.jpeg?w=1000)

Hey There,

I am expecting you are familiar with PHP. In this post I will be using the Laravel framework to create a small blog system. I am showing here very simple steps to create blogs, If you want this complete code then please message me.

**What are major Prequisites for Laravel:**

* PHP version >= 5.6

* Composer should be installed in system

Create a project with name tiny_blog with following command

```composer create-project laravel/laravel --prefer-dist tiny_blog```

enter into the laravel project

```cd tiny_blog```

create a migration file using following artisan command

<pre>php artisan make:migration create_blog_table</pre>

After this command you will found a new file created in database/migrations folder in your project, Just edit the file having 'create_blog_table' appended in its name

Now replace following code to create table schema with function up(), So now the method will look like following:

```

public function up()

{

Schema::create('blogs', function (Blueprint $table) {

$table->increments('id');

$table->integer('user_id');

$table->string('category');

$table->string('title');

$table->text('description');

$table->timestamps();

});

}

```

replace following snippet with down method, it will look like following:

```

public function down()

{

Schema::dropIfExists('blogs');

}

```

Its time to run the migration file we have created

```php artisan migrate```

After running,It will create the blogs table in database.Now time to create form and insert data into the table

Laravel itsef provide authentication , use following artisan command :

```php artisan make:auth```

Now start Larvel:

```php artisan serve```

it will start the laravel development server at `http://127.0.0.1:8000`

Now if you run that url the basic default ui will be created and login & register link you can see in Top right position of header

You can register and login now.this feature is provided by authentication module.

Now we need to create a controller for manage blogs with following command:

```php artisan make:controller BlogController```

will create a file named **BlogController.php** in** app/HTTP/controllers** folder location

Now we need to create a Model also, use following command

```php artisan make:model Blog```

will create a file named **Blog.php** in app folder location

Now in Controller we need to create a method for create blogs and available that method in Routes to access it via url. Just edit **routes/web.php** file and add the following line

```php

Route::get('blog/create','[email protected]');

```

__/create/blog/__ will be url route that land on Blog Controller's createBlog method using get method.

Now before running this route just go to the app/Http/Controllers folder and Edit BlogController.php file and Add the createBlog method in that class as following

```

public function createBlog()

{

return view('blog.create');

}

```

This code will try to load the view from **/resources/views/blog/create.blade.php**

In Laravel blade is a template engine. As we had not created the view file yet, so we need to create a blog folder inside **/resources/views/ ** folder then inside blog folder create a file

**create.blade.php** with following form

```

@extends('layouts.app')

@section('content')

<div class="container">

@if ($errors->any())

<div class="alert alert-danger">

<ul>

@foreach ($errors->all() as $error)

<li>{{ $error }}</li>

@endforeach

</ul>

</div><br />

@endif

<div class="row">

<form method="post" action="{{url('blog/create')}}">

<div class="form-group">

<input type="hidden" value="{{csrf_token()}}" name="_token" />

<label for="title">Title:</label>

<input type="text" class="form-control" name="title"/>

</div>

<div class="form-group">

<label for="title">Category/Tags:</label>

<input type="text" class="form-control" name="category"/>

</div>

<div class="form-group">

<label for="description">Description:</label>

<textarea cols="10" rows="10" class="form-control" name="description"></textarea>

</div>

<button type="submit" class="btn btn-primary">Submit</button>

</form>

</div>

</div>

@endsection

```

Now we need to add a additional route to handle the post request on blog/create route, Just edit routes/web.php file and just add following line in last:

```Route::post('blog/create','[email protected]'); ```

post route to handle the form post on route blog/create

Now create a method name saveBlog to save the user input data in the form

```

public function saveBlog(Request $request)

{

$blog = new Blog();

$this->validate($request, [

'title'=>'required',

'category'=>'required',

'description'=> 'required'

]);

$blog->createBlog($request->all());

return redirect('blog/index')->with('success', 'New blog has been created successfully :)');/ / the index method is the list blogs method that we will create in further lines

}

```

Notice This method is using Blog object that we don't know that where it comes from? , So to make above code working we need to include the model which we created earlier need to include in our controller file So use following code to include it before the class created.

```use App\Blog;```

Now following line shows that there is a method named createBlog in `Model(app/Blog.php)`, but in actual it is not there:

```php

$blog->createBlog($data);

```

So go to the file app/Blog.php and Edit it and inside the class add following method:

```php

public function createBlog($data)

{

$this->user_id = auth()->user()->id;

$this->title = $data['title'];

$this->description = $data['description'];

$this->category = $data['category'];

$this->save();

return 1;

}

```

Now the creation of blog task has been done , Its time to show the created Entries So just create a route blog/index in routes/web.php

```php

Route::get('blog/index','[email protected]');

```

get route blog/index to show all the created blogs by current user

Now just add a method in controller

```php

public function showAllBlogs()

{

$blogs = Blog::where('user_id', auth()->user()->id)->get();

return view('blog.index',compact('blogs'));

}

```

This method requires to create a index view in blog folder , So create a file named index.blade.php in /resources/views/blog/ folder with following code

```php

@extends('layouts.app')

@section('content')

<div class="container">

@if(\Session::has('success'))

<div class="alert alert-success">

{{\Session::get('success')}}

</div>

@endif

<a type="button" href="{{url('blog/create')}}" class="btn btn-primary">Add New Blog</a>

<br>

<table class="table table-striped">

<thead>

<tr>

<td>ID</td>

<td>Title</td>

<td>Category</td>

<td>Description</td>

<td colspan="2">Action</td>

</tr>

</thead>

<tbody>

@foreach($blogs as $blog)

<tr>

<td>{{$blog->id}}</td>

<td>{{$blog->title}}</td>

<td>{{$blog->category}}</td>

<td>{{$blog->description}}</td>

<td>Edit</td>

<td>Delete</td>

</tr>

@endforeach

</tbody>

</table>

<div>

@endsection

```

Now all code is ready but we need to add 1 line of code to prevent the blog controller without authentication or without login

just add the following constructor method in BlogController class

```php

public function __construct()

{

$this->middleware('auth');

}

```

this constructor method will call very first when user will try to access any of BlogController class method, and the middleware will check whether user is logged in then only it will allow to access that method otherwise it will redirect to login page automatically.

After It Run your Code and you will able to create and listing your created blogs/articles. but the Edit and Delete links are not working right now, If you want that also working then please comment here or message me. If we get multiple requests then definitely i will write its part 2 article

Thanks very much for reading this blog, if you have any doubt about it then let me know in comments or by messaging me.

Following is the final code for BlogController.php

```php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Blog;

class BlogController extends Controller

{

public function __construct()

{

$this->middleware('auth');

}

public function createBlog()

{

return view('blog/create');

}

public function saveBlog(Request $request)

{

$blog = new Blog();

$this->validate($request, [

'title'=>'required',

'category'=>'required',

'description'=> 'required'

]);

$blog->createBlog($request->all());

return redirect('blog/index')->with('success', 'New blog has been created successfully :)');

}

public function showAllBlogs()

{

$blogs = Blog::where('user_id', auth()->user()->id)->get();

return view('blog.index',compact('blogs'));

}

}

```

7725 views · 2 years ago

![PHP IPC with Daemon Service using Message Queues, Shared Memory and Semaphores](https://images.ctfassets.net/vzl5fkwyme3u/4ULcw2rCysGcSGOAi2uKOk/450013591b84069c5536663430536714/AdobeStock_200383770.jpeg?w=1000)

# Introduction

In a previous article we learned about [Creating a PHP Daemon Service](https://beta.nomadphp.com/blog/50/creating-a-php-daemon-service). Now we are going to learn how to use methods to perform IPC - Inter-Process Communication - to communicate with daemon processes.

# Message Queues

In the world of UNIX, there is an incredible variety of ways to send a message or a command to a daemon script and vice versa. But first I want to talk only about message queues - "System V IPC Messages Queues".

A long time ago I learned that a queue can be either in the System V IPC implementation, or in the POSIX implementation. I want to comment only about the System V implementation, as I know it better.

Lets get started. At the "normal" operating system level, queues are stored in memory. Queue data structures are available to all system programs. Just as in the file system, it is possible to configure queues access rights and message size. Usually a queue message size is small, less than 8 KB.

This introductory part is over. Lets move on to the practice with same example scripts.

**queue-send.php**

```php

/ / Convert a path name and a project identifier to a System V IPC key

$key = ftok(__FILE__, 'A'); / / 555 for example

/ / Creating a message queue with a key, we need to use an integer value.

$queue = msg_get_queue($key);

/ / Send a message. Note that all required fields are already filled,

/ / but sometimes you want to serialize an object and put on a message or a lock.

/ / Note that we specify a different type. Type - is a certain group in the queue.

msg_send($queue, 1, 'message, type 1');

msg_send($queue, 2, 'message, type 2');

msg_send($queue, 3, 'message, type 3');

msg_send($queue, 1, 'message, type 1');

echo "send 4 messages

";

```

**queue-receive.php**

```php

$key = ftok('queue-send.php', 'A'); / / 555 for example

$queue = msg_get_queue($key);

/ / Loop through all types of messages.

for ($i = 1; $i <= 3; $i++) {

echo "type: {$i}

";

/ / Loop through all, read messages are removed from the queue.

/ / Here we find a constant MSG_IPC_NOWAIT, without it all will hang forever.

while ( msg_receive($queue, $i, $msgtype, 4096, $message, false, MSG_IPC_NOWAIT) ) {

echo "type: {$i}, msgtype: {$msgtype}, message: {$message}

";

}

}

```

Lets run on the first stage of the file queue-send.php, and then queue-receive.php.

```sh

u% php queue-send.php

send 4 messages

u% php queue-receive.php

type: 1

type: 1, msgtype: 1, message: s:15:"message, type 1";

type: 1, msgtype: 1, message: s:15:"message, type 1";

type: 2

type: 2, msgtype: 2, message: s:15:"message, type 2";

type: 3

type: 3, msgtype: 3, message: s:15:"message, type 3";

```

You may notice that the messages have been grouped. The first group gathered 2 messages of the first type, and then the remaining messages.

If we would have indicated to receive messages of type 0, you would get all messages, regardless of the type.

```php

while (msg_receive($queue, $i, $msgtype, 4096, $message, false, MSG_IPC_NOWAIT)) {

/ / ...

```

Here it is worth noting another feature of the queues: if we do not use the constant MSG_IPC_NOWAIT in the script and run the script queue-receive.php from a terminal, and then run periodically the file queue-send.php, we see how a daemon can effectively use this to wait jobs.

**queue-receive-wait.php**

```php

$key = ftok('queue-send.php', 'A'); / / 555 for example

$queue = msg_get_queue($key);

/ / Loop through all types of messages.

/ / Loop through all, read messages are removed from the queue.

while ( msg_receive($queue, 0, $msgtype, 4096, $message) ) {

echo "msgtype: {$msgtype}, message: {$message}

";

}

```

Actually that is the most interesting information of all I have said. There are also functions to get statistics, disposal and checking for the existence of queues.

Lets now try to write a daemon listening to a queue:

**queue-daemon.php**

```php

/ / Fork process

$pid = pcntl_fork();

$key = ftok('queue-send.php', 'A');

$queue = msg_get_queue($key);

if ($pid == -1) {

exit;

} elseif ($pid) {

exit;

} else {

while ( msg_receive($queue, 0, $msgtype, 4096, $message) ) {

echo "msgtype: {$msgtype}, message: {$message}

";

}

}

/ / Disengaged from the terminal

posix_setsid();

```

# Shared Memory

We have learned to work with queues, with which you can send small system messages. But then we may certainly be faced with the task of transmitting large amounts of data. My favorite type of system, System V, has solved the problem of rapid transmission and preservation of large data in memory using a mechanism called **Shared Memory**.

In short, the data in the Shared Memory lives until the system is rebooted. Since the data is in memory, it works much faster than if it was stored in a database somewhere in a file, or, God forgive me on a network share.

Lets try to write a simple example of data storage.

**shared-memory-write-base.php**

```php

/ / This is the correct and recommended way to obtain a unique identifier.

/ / Based on this approach, the system uses the inode table of the file system

/ / and for greater uniqueness converts this number based on the second parameter.

/ / The second parameter always goes one letter

$id = ftok(__FILE__, 'A');

/ / Create or open the memory block

/ / Here you can specify additional parameters, in particular the size of the block

/ / or access rights for other users to access this memory block.

/ / We can simply specify the id instead of any integer value

$shmId = shm_attach($id);

/ / As we have shared variables (any integer value)

$var = 1;

/ / Check if we have the requested variables.

if (shm_has_var($shmId, $var)) {

/ / If so, read the data

$data = (array) shm_get_var($shmId, $var);

} else {

/ / If the data was not there.

$data = array();

}

/ / Save the in the resulting array value of this file.

$data[time()] = file_get_contents(__FILE__);

/ / And writes the array in memory, specify where to save the variable.

shm_put_var($shmId, $var, $data);

/ / Easy?

```

Run this script several times to save the value in memory. Now lets write a script only to read from the memory.

**shared-memory-read-base.php**

```php

/ / Read data from memory.

$id = ftok(__DIR__ . '/shared-memory-write-base.php', 'A');

$shmId = shm_attach($id);

$var = 1;

/ / Check if we have the requested variables.

if (shm_has_var($shmId, $var)) {

$data = (array) shm_get_var($shmId, $var);

} else {

$data = array();

}

/ / Iterate received and save them to files.

foreach ($data as $key => $value) {

/ / A simple example, create a file from the data that we have saved.

$path = "/tmp/$key.php";

file_put_contents($path, $value);

echo $path . PHP_EOL;

}

```

# Semaphores

So, in general terms, it should be clear for you by now how to work with shared memory. The only problems left to figure out are about a couple of nuances, such as: "What to do if two processes want to record one block of memory?" Or "How to store binary files of any size?".

To prevent simultaneous accesses we will use semaphores. Semaphores allow us to flag that we want to have exclusive access to some resource, like for instance a shared memory block. While that happens other processes will wait for their turn on semaphore.

In this code it explained clearly:

**shared-memory-semaphors.php**

```php

/ / Let's try to save a binary file, the size of a couple of megabytes.

/ / This script does the following:

/ / If there is input, it reads it, otherwise it writes data into memory

/ / In this case, when writing to the memory we put a sign lock - semaphore

/ / Everything is as usual, read the previous comments

$id = ftok(__FILE__, 'A');

/ / Obtain a resource semaphore - lock feature. There is nothing wrong if we

/ / use the same id that is used to obtain a resource shared memory

$semId = sem_get($id);

/ / Put a lock. There's a caveat. If another process will encounter this lock,

/ / it will wait until the lock is removed

sem_acquire($semId);

/ / Specify your like picture

$data = file_get_contents(__DIR__.'/06050396.JPG', FILE_BINARY);

/ / These can be large, so precaution is necessary to allocate such a way that would be enough

$shmId = shm_attach($id, strlen($data)+4096);

$var = 1;

if (shm_has_var($shmId, $var)) {

/ / Obtain data from the memory

$data = shm_get_var($shmId, $var);

/ / Save our file somewhere

$filename = '/tmp/' . time();

file_put_contents($filename, $data, FILE_BINARY);

/ / Remove the memory block that started it all over again.

shm_remove($shmId);

} else {

shm_put_var($shmId, $var, $data);

}

/ / Releases the lock.

sem_release($semId);

```

Now you can use the md5sum command line utility to compare two files, the original and the saved file. Or, you can open the file in image editor or whatever prefer to compare the images.

With this we are done with shared memory and semaphores. As your homework I want to ask you to write code that a demon will use semaphores to access shared memory.

# Conclusion

Exchanging data between the daemons is very simple. This article described two options for data exchange: message queues and shared memory.

Post a comment here if you have questions or comments about how to exchange data with daemon services in PHP.

8224 views · 2 years ago

![Making Charts and Graphs using Laravel](https://images.ctfassets.net/vzl5fkwyme3u/5BTS4j0szSISc42GiMM64C/4261e509221448298776024a6f6629cd/AdobeStock_203669380.jpeg?w=1000)

## Installing composer

Composer is a package management tool for PHP. Laravel requires composer for installation. We can download composer from [https://getcomposer.org/download/](https://getcomposer.org/download/)

After installation that you can test whether composer installed or not by command

composer

## Installing Laravel

The current stable version of laravel is laravel 5.6. We can install laravel package with three ways.

In command prompt or terminal by running `composer global require "laravel/installer"` and then `Laravel new `

**or**

We can create the project with Composer by running `composer create-project --prefer-dist laravel/laravel `

**or**

Directly clone from github

`git clone https://github.com/laravel/laravel/tree/master` and after that composer update

### Laravel local development server

Run the below command in command prompt or terminal

`PHP artisan serve`

Above command will start to local development servehttp://localhost:8000 or if you want to change default port:

```php

php artisan serve --port

```

## Generating charts and graphs

We are using consoletvs package for generating charts. So for installation we can first move inside to our project using command prompt or terminal. We are following the below steps to install

### Step 1:

First we need to install ConsoleTVs/Charts composer package inside our laravel project.

```php

composer require consoletvs/charts```

### Step 2:

After successfully installation of above package, open app/config.php and add service provider.

In `config/app.php`

```php

'providers' => [

....

ConsoleTVs\Charts\ChartsServiceProvider::class,

],```

After the service provider we need to add alias

```php

'aliases' => [

....

'Charts' => ConsoleTVs\Charts\Facades\Charts::class,

]```

### Step 3

We need to configure of database for application. We can configure in either `.env` file or `config/database.php` file.

### Step 4

We can migrate our default tables that is user. We can find the table in `database/migration` folder.

### Step 5

We can generate dummy records for demo in users table. For creating dummy records, we need to run the below command in command prompt or terminal

```php artisan tinker>>> factory(App\User::class, 20)->create();```

the above command will create a set of 20 records.

If we need to add more records we need to run the above command or we can increase the count as much as we want. For example

```php artisan tinker>>> factory(App\User::class, 2000)->create();```

### Step 6

**Creating controller**

For creating controller we need to run below command in terminal or command prompt

```php

php artisan make controller:<controller_name>```

### Step 7

**Adding the routes**

We can add the routes for navigating our application. You can find routes file inside routes folder. Before 5.4 we can find routes.php file itself, now its web.php. If you are using laravel 5.2 routes.php will inside app/http folder.

So inside `web.php`:

```php

Route::get('create-chart/{type}','[email protected]');```

Here type will be the parameter we are passing and it will focus to `makeChart()` function inside chartcontroller

### Step 8

Import charts to controller, for that in the namespace section add:

```php

Use charts;```

### Step 9

We can put the below code into chartController

```php

public function makeChart($type)

{

switch ($type) {

case 'bar':

$users = User::where(DB::raw("(DATE_FORMAT(created_at,'%Y'))"),date('Y'))

->get();

$chart = Charts::database($users, 'bar', 'highcharts')

->title("Monthly new Register Users")

->elementLabel("Total Users")

->dimensions(1000, 500)

->responsive(true)

->groupByMonth(date('Y'), true);

break;

case 'pie':

$chart = Charts::create('pie', 'highcharts')

->title('HDTuto.com Laravel Pie Chart')

->labels(['Codeigniter', 'Laravel', 'PHP'])

->values([5,10,20])

->dimensions(1000,500)

->responsive(true);

break;

case 'donut':

$chart = Charts::create('donut', 'highcharts')

->title('HDTuto.com Laravel Donut Chart')

->labels(['First', 'Second', 'Third'])

->values([5,10,20])

->dimensions(1000,500)

->responsive(true);

break;

case 'line':

$chart = Charts::create('line', 'highcharts')

->title('HDTuto.com Laravel Line Chart')

->elementLabel('HDTuto.com Laravel Line Chart Lable')

->labels(['First', 'Second', 'Third'])

->values([5,10,20])

->dimensions(1000,500)

->responsive(true);

break;

case 'area':

$chart = Charts::create('area', 'highcharts')

->title('HDTuto.com Laravel Area Chart')

->elementLabel('HDTuto.com Laravel Line Chart label')

->labels(['First', 'Second', 'Third'])

->values([5,10,20])

->dimensions(1000,500)

->responsive(true);

break;

case 'geo':

$chart = Charts::create('geo', 'highcharts')

->title('HDTuto.com Laravel GEO Chart')

->elementLabel('HDTuto.com Laravel GEO Chart label')

->labels(['ES', 'FR', 'RU'])

->colors(['#3D3D3D', '#985689'])

->values([5,10,20])

->dimensions(1000,500)

->responsive(true);

break;

default:

/ / code...

break;

}

return view('chart', compact('chart'));

}```

### Step 10

Create a blade file. Blade is the view file used inside the laravel. You can add new blade file with any name with an extension of .blade.php

Here we are creating chart.blade.php

```html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>My Charts</title>

{!! Charts::styles() !!}

</head>

<body>

<div class="app">

<center>

{!! $chart->html() !!}

</center>

</div>

{!! Charts::scripts() !!}

{!! $chart->script() !!}

</body>

</html>

```

### Step 11

We can run our laravel application in local development server by `php artisan serve` command:

```

http://localhost:8000/create-chart/bar

http://localhost:8000/create-chart/pie

http://localhost:8000/create-chart/donut

http://localhost:8000/create-chart/line

http://localhost:8000/create-chart/area

http://localhost:8000/create-chart/geo

```

In the above example we was creating line chart, geo chart, bar chart, pie chart, donut chart, line chart and area chart. We can also create gauge chart, progressbar chart, areaspline chart, scatter chart, percentage chart etc using consoletvs charts composer package.

There are a lot of jQuery libraries also available like amcharts, chartjs, highcharts, google, material, chartist, fusioncharts, morris, plottablejs etc. However, using this plugin we can easily create charts without having to use jQuery, another advantage to building it in with Laravel.

3862 views · 2 years ago

Now that the Thanksgiving and Black Friday are left behind, we're all back at our desks, some of us having PHPStorm open for the whole day. In this post, I'll say a few words on this [beautiful IDE](https://www.jetbrains.com/phpstorm/), [PHPUnit](https://phpunit.de/) and [XDebug](https://xdebug.org/).

**You know that unit tests are essential, don't you?** So do the PHPStorm developers. This industry-standard level IDE has tons of capabilities for integrating test frameworks and debuggers into your project. Even if you use VMs or containers to run your development environment, chances are they got you covered!

![Blind Pew from Treasure Island](https://i.imgflip.com/2ne1bt.jpg)

I often see even experienced PHP programmers debugging their code with `var_dump()`, which is obviously not the best way to do it. If you see the code for the first time, if you work with legacy code - step-by-step interactive debugging is the way to go. Sometimes it can save you hours of old school var_dumping.

As of unit tests, I often hear that it's good enough to run tests from the terminal. I even know a guy who runs `watch phpunit /path/to/test` while developing: this way the test is run every 2 seconds, you switch to the terminal whenever you want to see the latest results and that's it. However, there are certain advantages in running tests from the IDE. First, it's super-handy to launch a test method, test class or a whole folder with tests, just by pressing a hotkey. Second, the test results appear right there, in PHPStorm, with failures and their stack traces, every entry clickable and takes you directly to the file:line where a nasty thing happened. I also find the ability to run a debugger for a unit test, extremely attractive. Test fails, you click on a trace entry, get to a problematic line, place a break point, re-run the test in debug mode - and there you go.

For all those integrations, you will first need to setup the PHP interpreter for the project: [Configuring PHP Development Environment](https://www.jetbrains.com/help/phpstorm/configuring-php-development-environment.html). You will find both local and remote interpreter setups. "Local" is the PHP that you have on your workstation, the host machine. "Remote" can be pretty much everything: SSH if your Dev environment runs on a shared sandbox for all developers, docker or docker-compose if you run it using docker containers.

Next step - creating PHPUnit configuration. Go to _Settings -> Languages and Frameworks -> PHP -> Test Frameworks_. Follow [this guide](https://www.jetbrains.com/help/phpstorm/enabling-php-unit-support.html), it has much more information which will be more up-to-date than this post. **Don't forget to set Path Mappings for your remote environments**! That is, you probably have your project in, say, `$HOME/projects/cool-project`, but inside a docker or on a remote host it might be located at `/app` or `/var/www`, then you have to let PHPStorm know about this.

Once you're done with PHPUnit setup, you can finally [run your tests](https://www.jetbrains.com/help/phpstorm/enabling-php-unit-support.html#run_phpunit_tests)! The default shortcut on my Linux machine is _Ctrl+Shift+F10_ (shortcuts are usually different on Mac though). Place a cursor inside a test method, press the shotcut: PHPStorm will launch PHPUnit with **that particular test method**! When the cursor in a scope of test class but not inside a test method - the whole test class will be run. And, you also can select a whole folder with tests, in the project tree and run it, ain't that cool?

A small tip for the docker-compose lovers. When I first set PHPStorm integration with docker-compose and ran the tests, I was quite surprised (unpleasantly) to see that my _php-fpm_ service that I was connecting to, is gone after the test process is finished. Took me some time to figure out that it's PHPStorm's expected behavior. It stops the target service after it's done testing. A workaround I started to use is as follows: I just add another service called _phpunit_ which uses a php-fpm or php-cli image, and is not needed by anything except unit testing in PHPStorm.

### Now to debugging.

> Debugging is like being the detective in a crime movie where you are also the murderer. [Filipe Fortes a.k.a. @fortes](https://twitter.com/fortes/status/399339918213652480)

Obviously, your PHP interpreter in development environment will need a debugger extension in order for you to debug interactively. PHPStorm support the two most widely used options: [XDebug](https://xdebug.org) and [Zend Debugger](http://www.zend.com/en/community/pdt). When using docker I usually make a separate Dockerfile for development, using production image as base, then add development tools, **XDebug** being the most important. Honestly, I've never used **Zend Debugger**, so have little to tell about its' nuances.

Got an extension? Go to [Debugging Ultimate Guide](https://www.jetbrains.com/help/phpstorm/debugging-with-phpstorm-ultimate-guide.html)! Debugger settings in PHPStorm are at _Settings -> Languages and Frameworks -> PHP -> Debug_. Most of the time you don't need to change them. **Again, a note for docker-compose users**. There is an XDebug setting that allow debugger to resolve the client (PHPStorm) IP address: _xdebug.remote_connect_back_. That's a disappointment but those will not work, at least with a default docker-compose setup. Thing is, all containers in a compose stack are running behind a network proxy provided by docker-compose. That is, the REMOTE_ADDR for all the containers will always be the IP of proxy. A workaround:

* disable _xdebug.remote_connect_back_;

* add _.user.ini_ to the application root folder with the following contents: _xdebug.remote_host = 192.168.X.X_ (your machine's IP address in the LAN). It's generally a good idea to exclude _.user.ini_ from VCS control.

As a conclusion: if you still use _var_dump()_ to debug, stop living in the stone age, upgrade your knowledge and become more productive! If you don't write unit tests, start doing it. If your managers say it's a waste of time, tell them that it's coding without tests that is a waste of time. And, if you find this post of any use, or have an opinion, or a question - please do comment!

SPONSORS

Faster PHP Cloud Hosting