PHP & Web Development Blogs

Showing 31 to 35 of 49 blog articles.
3987 views · 2 years ago

![Press Release](https://images.ctfassets.net/vzl5fkwyme3u/6iJumo9OXCq0m0EqOuueAm/61e3dea3c18f9d770a6906099856e015/press_release.jpeg?w=1000)

To say that we have been hard at work here at Nomad PHP, or that I'm excited about these three announcements would be a tremendous understatement. Over the past several months, behind the scenes, we've been working to bring even more features and benefits to Nomad PHP - these have already included unlimited streaming of all past meetings and access to PHP Architect.

Available today, however, you'll also have access to online, live workshops - as well as soon have the ability to stream select PHP conferences live, and finally to prove the knowledge you have gained through our online certification.

## Online, Live Workshops

Like our online meetings, we are excited to announce that available today you can participate in online, live, and interactive workshops. Our [first workshop](https://beta.nomadphp.com/live/bC7lqFvjeouMoC4cqoaU6/Workshop--Achieving-Undisturbed-REST--Part-1-/) will feature Michael Stowe, author of Undisturbed REST: a guide to Designing the Perfect API as he demonstrates how to build the perfect API using modern technologies and techniques.

Additional workshops will be announced as we continue, with a minimum of one workshop per quarter. These workshops will be part of your Nomad PHP subscription, and will be recorded for later viewing.

## Nomad PHP Certification

With the many changes impacting the PHP ecosystem, we're proud to announce the ability to prove your knowledge with our online certification. Each certification is made up numerous, randomly selected questions to be completed within a specific time frame. Depending on the exam it may or may not be proctored, but all exams monitor user activity to ensure compliance.

To pass the exam, a passing grade (specified on each exam) must be completed for each section within the allotted time frame. Failure to complete or pass any section will result in a failing grade for the entire exam.

Upon completion, you will receive a digital certification with verification to post on LinkedIn or your website, as well as having your Nomad PHP updated to show the passed certification.

Initial certification exams will include PHP Developer Level I, PHP Engineer Level II, and API Specialist Level I. The PHP Developer exam will cover core components of PHP, the Engineer will cover a broad spectrum of topics including modern technologies, and the API Specialist will cover REST design and architecture practices.

All three exams will be available by January 31, 2019, and will be included with a Nomad PHP subscription.

## Stream Select PHP Conferences Live

One of the primary goals of Nomad PHP is to bring the community together, and allow users all over the country to participate in conference level talks. What better way to do this than to bring community conferences online?

Like our traditional talks, these conferences and select conference sessions will be live-streamed as part of your Nomad PHP subscription, allowing you to participate in real-time with in-person conference attendees.

The first conference to be streamed will be [DayCamp4Developers: Beyond Performance](https://daycamp4developers.com/) on January 18, 2018. Additional conferences to be streamed will be announced shortly.

## Community and Corporate Sponsorships

With these new additions to Nomad PHP, now is the perfect time to take advantage of our new [Community and Corporate sponsorships](/static/advertise).

Your support of Nomad PHP not only makes all the above possible, but allows Nomad PHP to continue to serve and give back the community. We're proud, that despite operating at a loss, to have already contributed over **$4,000** to the PHP community in the last 5 months.

To learn more about the sponsorship and community opportunities we have available, please visit our [Advertising section](/static/advertise).

### Other Ways to Support Nomad PHP

Of course, while financial support helps us keep afloat and do more for the community, there are even more, and just as important ways to support Nomad PHP. Please consider [linking to Nomad PHP](/static/webmasters), or [sharing the service](/invite) with your friends.

3846 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);

}

}

```

6655 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'));

}

}

```

7402 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.

7398 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.

SPONSORS