PHP & Web Development Blogs

Search Results For: from
Showing 6 to 10 of 57 blog articles.
24726 views · 4 years ago
PHP CHAT WITH SOCKETS

Hey Friends,

I am sharing a very interesting blog on how to create a chat system in php without using ajax. As we all know ajax based chat system in php is not a good solution
because itincreases the server load and redundant xhr calls on our server.

Instead, I am going to use sockets for incoming messages from and send messages to another user. So lets try them out using the following steps:


Step 1: Cross check in php.ini that sockets extension is enabled


;extension=sockets
extension=sockets


Step 2: Create server.php file


This file will handle the incoming and outgoing messages on sockets, Add following variables in top of the file:

$host = 'localhost';
$port = '9000';
$null = NULL; 


Step 3: After it add helper methods


The following code for handshake with new incoming connections and encrypt and decrypt messages incoming and outgoing over sockets:

function send_message($msg)
{
global $clients;
foreach($clients as $changed_socket)
{
@socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
function unmask($text) {
$length = ord($text[1]) & 127;
if($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
}
else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);

if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header.$text;
}
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/

/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake

" .
"Upgrade: websocket

" .
"Connection: Upgrade

" .
"WebSocket-Origin: $host

" .
"WebSocket-Location: ws://$host:$port/php-ws/chat-daemon.php

".
"Sec-WebSocket-Accept:$secAccept



";
socket_write($client_conn,$upgrade,strlen($upgrade));
}


Step 4: Now add following code to create bind and listen tcp/ip sockets:


$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socket, 0, $port);
socket_listen($socket);
$clients = array($socket);


Ok now a endless loop that will use for handeling incominga nd send messages:

while (true) {
$changed = $clients;
socket_select($changed, $null, $null, 0, 10);

if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); $clients[] = $socket_new;
$header = socket_read($socket_new, 1024); perform_handshaking($header, $socket_new, $host, $port);
socket_getpeername($socket_new, $ip); $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); send_message($response);
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}

foreach ($changed as $changed_socket) {

while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); $tst_msg = json_decode($received_text, true); $user_name = $tst_msg['name']; $user_message = $tst_msg['message']; $user_color = $tst_msg['color'];
$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
send_message($response_text); break 2; }

$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { $found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);

$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
send_message($response);
}
}
}
socket_close($socket);


So you are ready with server side socket program, Now its time to move on front side where we will implement w3c provided client side Web Socket Apis,

Step 5: create a file named index.php for frontend usage with following initial code


$host = 'localhost';
$port = '9000';
$subfolder = "php_ws/";
$colors = array('#007AFF','#FF7000','#FF7000','#15E25F','#CFC700','#CFC700','#CF1100','#CF00BE','#F00');
$color_pick = array_rand($colors);
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="chat-wrapper">
<div id="message-box"></div>
<div class="user-panel">
<input type="text" name="name" id="name" placeholder="Your Name" maxlength="15" />
<input type="text" name="message" id="message" placeholder="Type your message here..." maxlength="100" />
<button id="send-message">Send</button>
</div>
</div>
</body>
</html>


Now add some basic styling in the head section using following code:

<style type="text/css">
.chat-wrapper {
font: bold 11px/normal 'lucida grande', tahoma, verdana, arial, sans-serif;
background: #00a6bb;
padding: 20px;
margin: 20px auto;
box-shadow: 2px 2px 2px 0px #00000017;
max-width:700px;
min-width:500px;
}
#message-box {
width: 97%;
display: inline-block;
height: 300px;
background: #fff;
box-shadow: inset 0px 0px 2px #00000017;
overflow: auto;
padding: 10px;
}
.user-panel{
margin-top: 10px;
}
input[type=text]{
border: none;
padding: 5px 5px;
box-shadow: 2px 2px 2px #0000001c;
}
input[type=text]#name{
width:20%;
}
input[type=text]#message{
width:60%;
}
button#send-message {
border: none;
padding: 5px 15px;
background: #11e0fb;
box-shadow: 2px 2px 2px #0000001c;
}
</style>


Ok Style is all set now need to add a jquery script and create web socket object and handle all events on it as following code need to add before closing of bosy tag:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
var msgBox = $('#message-box');
var wsUri = "ws://".$host.":".$port."/php-ws/server.php";
websocket = new WebSocket(wsUri);

websocket.onopen = function(ev) { msgBox.append('<div class="system_msg" style="color:#bbbbbb">Welcome to my "Chat box"!</div>'); }
websocket.onmessage = function(ev) {
var response = JSON.parse(ev.data);
var res_type = response.type; var user_message = response.message; var user_name = response.name; var user_color = response.color; switch(res_type){
case 'usermsg':
msgBox.append('<div><span class="user_name" style="color:' + user_color + '">' + user_name + '</span> : <span class="user_message">' + user_message + '</span></div>');
break;
case 'system':
msgBox.append('<div style="color:#bbbbbb">' + user_message + '</div>');
break;
}
msgBox[0].scrollTop = msgBox[0].scrollHeight; };

websocket.onerror = function(ev){ msgBox.append('<div class="system_error">Error Occurred - ' + ev.data + '</div>'); };
websocket.onclose = function(ev){ msgBox.append('<div class="system_msg">Connection Closed</div>'); };
$('#send-message').click(function(){
send_message();
});

$( "#message" ).on( "keydown", function( event ) {
if(event.which==13){
send_message();
}
});

function send_message(){
var message_input = $('#message'); var name_input = $('#name');
if(message_input.val() == ""){ alert("Enter your Name please!");
return;
}
if(message_input.val() == ""){ alert("Enter Some message Please!");
return;
}
var msg = {
message: message_input.val(),
name: name_input.val(),
color : '<?php echo $colors[$color_pick]; ?>'
};
websocket.send(JSON.stringify(msg));
message_input.val(''); }
</script>


Ok All set, Now need to run the server.php file using following php-cli utility,make sure you have php cli utility installed in your system:

php -q c:\xampp\htdocs\php-ws\server.php


Now you may access the front index.php file via the browser url like following and see a chatbox and connection status, you may use the same url or different browser to check the chat system is working or not.
7772 views · 5 years ago
Standalone PHP Class for Managing Session Based Multiple Cart

Hi Guys,

I am sharing you a standalone class for managing a session based cart system. In this class I have provided multiple methods for adding, updating and deleting the products. and By using this class you may manage multiple cart objects with different data only you need to pass a different key in constructor of that class.

Let me share you the How can we use that Class:


Include The cart class


require 'PhpKart.class.php';



Create a Cart Object initializing the Cart base key name, by using different keys we can manage multiple cart data in a same project , like main cart or wishlist


$obj1 = new PhpKart("MainCart");


Here Maincart is the keyname in which $obj1 insert/modify/delete the data


Adding any product inside cart


$obj1->add_to_cart($product_id=123,$quantity=2,$product_information=array("product_name"=>"Tomato","Price"=>20));


Where parameter1 is product, id,parameter 2 is quantity, and Parameter 3 is product information Array


Now If we want to update the quantity in product_id=123 with quantity 5 then use following:


$obj1->add_to_cart($product_id=123,$quantity=5);


Here we did not pass the information array again because no matter you pass or not if the product information is already added in the cart then if won't be affected So no ned to pass this, only pass product id and its Quantity


If we want to add another product:


$obj1->add_to_cart($product_id=145,$quantity=3,$product_information=array("product_name"=>"Potato","Price"=>30));



Now we have a case what if our product is already having some quantity and we want to increase into it or decrease into it, Then to retrieve the already added product information, using AlreadyExists method by passing product id,it will return array if it exists and it will return boolean false if not exists:


$already_exists=$obj1->AlreadyExists($product_id=145); 
if($already_exists !== false )
{
print_r($already_exists);
}



If we want to remove any product from cart:


$obj1->remove_from_cart($product_id=145);



If we want to get all products from the current cart


print_r( $obj1->getAllItems() );


It will return you an array with all the items exist in the current cart



Getting all item's count inside the current cart


echo $obj1->getTotalItems(); 



If we want to get calculate total amount in the current cart


echo $obj1->getCartTotalAmount($priceKeyName='Price')


Note: In the above snippet we need to provide teh same key name which we have used for product price in project information array at the time of adding items in cart array, and need to take the same key name in all the products inserting in Same Cart



If we want to clear/reset the current cart then use following:


$obj1->clear_cart(); 


Now if we want to save some other user interested items separately which use likes but don't want to buy now so that items can be Add into wishlist So we need to create new object with different cart ket name and that list will be manage separately using it's object. Like Following:



Create new Object by passing different Key

$obj2=new PhpKart("MyWishlist"); 



Add a new item to $obj2 object containing the items user want to add in his/her wishlist


$obj2->add_to_cart($product_id=159,$quantity=8,$product_information=array("product_name"=>"Baby Toy","Price"=>100));



Show the total cart Amount


echo $obj2->getCartTotalAmount("Price"); 



Full Source Code


Following is the full code for that cart managing Class . Just create a file named PhpKart.class.php and add following code in it:

<?php 
if(!session_id()){
@session_start();
}


class PhpKart{

private $cart_key;

public function __construct($CartkeyName)
{
$this->cart_key=$CartkeyName;
}
public function add_to_cart($product_id,$quantity='1',$product_information=array())
{
$_SESSION[$this->cart_key][$product_id]['product_id']=$product_id;
$_SESSION[$this->cart_key][$product_id]['quantity']=$quantity;
if(!isset($_SESSION[$this->cart_key][$product_id]['product_information']) && !empty($product_information)){
$_SESSION[$this->cart_key][$product_id]['product_information']=$product_information;
}
}
public function remove_from_cart($product_id)
{
unset($_SESSION[$this->cart_key][$product_id]);
}
public function clear_cart()
{
unset($_SESSION[$this->cart_key]);
}
public function getTotalItems()
{
return count($_SESSION[$this->cart_key]);
}
public function getCartTotalAmount($price_key_name)
{
$total=0;
foreach($_SESSION[$this->cart_key] as $row)
{
$total += ($row['product_information'][$price_key_name]*$row['quantity']);
}

return $total;
}
public function AlreadyExists($product_id)
{
if (isset($_SESSION[$this->cart_key][$product_id]))
{
return $_SESSION[$this->cart_key][$product_id];
}
else
{
return false;
}
}
public function getAllItems()
{
return $_SESSION[$this->cart_key];
}


}

?>

7689 views · 5 years ago
Iterator in PHP

Every time I see this
$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?

public function getUsers(): array
{

return $userArray;
}

public function setUsersToActiveState()
{
$users = $this->getUsers();

foreach ($users as $user) {
if(!$user->getActiveStatus()) {
$user->setActiveStatus(true);
}
}
}

There immediately two problems occurred.
    . 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 above foreach, it works for phpStorm and I guess for some other IDEs)
    . Your colleagues! How they possibly know what's inside array if there is no any hint.
    . Bonus problem, getUsers can return literally any array and there won't be warning in the system.

Solution



class UsersCollection implements \IteratorAggregate
{

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;
}
}

class UserIterator implements \Iterator
{

private $position = 0;


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.

class UsersCollectionTest extends TestCase
{

public function testUsersCollectionShouldReturnNullForNotExistingUserPosition()
{
$usersCollection = new UsersCollection();

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


public function testEmptyUsersCollection()
{
$usersCollection = new UsersCollection();

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

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


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()
{
}
}


class UserIteratorTest extends MockClass
{

public function testCurrent()
{
$iterator = $this->getIterator();
$current = $iterator->current();

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


public function testNext()
{
$iterator = $this->getIterator();
$iterator->next();

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


public function testKey()
{
$iterator = $this->getIterator();

$iterator->next();
$iterator->next();

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


public function testValidIfItemInvalid()
{
$iterator = $this->getIterator();

$iterator->next();
$iterator->next();
$iterator->next();

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


public function testValidIfItemIsValid()
{
$iterator = $this->getIterator();

$iterator->next();

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


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()
{
}
}


Usage


public function getUsers(): UsersCollection
{
$userCollection = new UsersCollection();

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.

 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.

public function addUsers(array $users)
{
foreach($users as $user) {
$this->addUser(User $users);
}
}

15385 views · 5 years ago
Create Alarm and Monitoring on Custom Memory and Disk Metrics for Amazon EC2

Today I am going write a blog on how to Monitor Memory and Disk custom metrics and creating alarm in Ubuntu.

To do this, we can use Amazon CloudWatch, which provides a flexible, scalable and reliable solution for monitoring our server.

Amazon Cloud Watch will allow us to collect the custom metrics from our applications that we will monitor to troubleshoot any issues, spot trends, and configure operational performance. CloudWatch functions display alarms, graphs, custom metrics data and including statistics.

Installing the Scripts


Before we start installing the scripts for monitoring, we should install all the dependent packages need to perform on Ubuntu.

First login to your AWS server, and from our terminal, install below packages

sudo apt-get update
sudo apt-get install unzip
sudo apt-get install libwww-perl libdatetime-perl


Now Install the Monitoring Scripts


Following are the steps to download and then unzip we need to configure the Cloud Watch Monitoring scripts on our server:
1. In the terminal, we need to change our directory and where we want to add our monitoring scripts.
2. Now run the below command and download the source:

curl https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip -O

3. Now uncompress the currently downloaded sources using the following commands

unzip CloudWatchMonitoringScripts-1.2.2.zip && \

rm CloudWatchMonitoringScripts-1.2.2.zip && \

cd aws-scripts-mon


The directory will contain Perl scripts, because of the execution of these scripts only report memory run and disk space utilization metrics will run in our Ubuntu server.
Currently, our folder will contain the following files:
mon-get-instance-stats.pl - This Perl file is used to displaying the current utilization statistics reports for our AWS instance on which these file scripts will be executed.
mon-put-instance-data.pl - This Perl script file will be used for collecting the system metrics on our ubuntu server and which will send them to the Amazon Cloud Watch.
awscreds.template - This Perl script file will contain an example for AWS credentials keys and secret access key named with access key ID.
CloudWatchClient.pm - This Perl script file module will be used to simplify by calling Amazon Cloud Watch from using other scripts.
LICENSE.txt – This file contains the license details for Apache 2.0.
NOTICE.txt – This file contains will gives us information about Copyright notice.
4. For performing the Cloud Watch operations, we need to confirm that whether our scripts have corresponding permissions for the actions:

If we are associated with an IAM role with our EC2 Ubuntu instance, we need to verify that which will grant the permissions to perform the below-listed operations:

cloudwatch:GetMetricStatistics

cloudwatch:PutMetricData

ec2:DescribeTags

cloudwatch:ListMetrics


Now we need to copy the ‘awscreds.template’ file into ‘awscreds.conf’ by using the command below and which will update the file with details of the AWS credentials.

cp awscreds.template awscreds.conf

AWSAccessKeyId = my_access_key_id

AWSSecretKey = my_secret_access_key


Now we completed the configuration.

mon-put-instance-data.pl


This Perl script file will collect memory, disk space utilization data and swap the current system details and then it makes handling a remote call to Amazon Cloud Watch to reports details to the collected cloud watch data as a custom metrics.

We can perform a simple test run, by running the below without sending data to Amazon CloudWatch

./mon-put-instance-data.pl --mem-util --verify --verbose


Now we are going to set a cron for scheduling our metrics and we will send them to Amazon CloudWatch
1. Now we need to edit the crontab by using below command:

 crontab -e

2. Now we will update the file using the following query which will disk space utilization and report memory for particular paths to Amazon CloudWatch in every five minutes:

*/5 * * * * ~/STORAGE/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl --mem-util --mem-avail --mem-used --disk-space-util --disk-space-avail --disk-space-used --disk-path=/ --disk-path=/STORAGE --from-cron


If there is an error, the scripts will write an error message in our system log.

Use of Options

--mem-used
The above command will collect the information about used memory and which will send the details of the reports in MBs into the MemoryUsed metrics. This will give us information about the metric counts memory allocated by applications and the OS as used.
--mem-util
The above command will collect the information about memory utilization in percentages and which will send the details of the Memory Utilization metrics and it will count the usage of the memory applications and the OS.
--disk-space-util
The above command will collect the information to collect the current utilized disk space and which will send the reports in percentages to the DiskSpaceUtilization for the metric and for the selected disks.
--mem-avail
The above command will collect the information about the available memory and which will send the reports in MBs to the MemoryAvailable metrics details. This is the metric counts memory allocated by the applications and the OS as used.
--disk-path=PATH
The above command will collect the information and will point out the which disk path to report disk space.
--disk-space-avail
The above command will collect the information about the available disk space and which will send the reports in GBs to the DiskSpaceAvailable metric for the selected disks.
--disk-space-used
The above command will collect the information about the disk space used and which will send the reports in GBs to the DiskSpaceUsed metric for the selected disks.

The PATH can specify to point or any of the files can be located on which are mounted point for the filesystem which needs to be reported.

If we want to points to the multiple disks, then specify both of the disks like below:

--disk-path=/ --disk-path=/home


Setting an Alarm for Custom Metrics


Before we are going to running our Perl Scripts, then we need to create an alarm that will be listed in our default metrics except for the custom metrics. You can see some default metrics are listed in below image:



Once we completed setting the cron, then the custom metrics will be located in Linux System Metrics.

Now we are going to creating the alarm for our custom metrics
1. We need to open the cloudwatch console panel at https://console.aws.amazon.com/cloudwatch/home
2. Now navigate to the navigation panel, we need to click on Alarm and we can Create Alarm.
3. This will open a popup which with the list of the CloudWatch metrics by category.
4. Now click on the Linux System Metrics . This will be listed out with custom metrics you can see in the below pictures






5. Now we need to select metric details and we need to click on the NEXT button. Now we need to navigate to Define Alarm step.



6. Now we need to define an Alarm with required fields

Now we need to enter the Alarm name for identifying them. Then we need to give a description of our alarm.

Next, we need to give the condition with the maximum limit of bytes count or percentage when it notifies the alarm. If the condition satisfies, then the alarm will start trigger.

We need to provide a piece of additional information about for our alarm.

We need to define what are the actions to be taken when our alarm changes it state.

We need to select or create a new topic with emails needed for sending notification about alarm state.
7. Finally, we need to choose the Create Alarm.

So its completed. Now the alarm is created for our selected custom metrics.

Finished!

Now the alarm will be listed out under the selected state in our AWS panel. Now we need to select an alarm from the list seen and we can see the details and history of our alarm.
14015 views · 5 years ago
Laravel Eloquent Relationship Part 1

Laravel introduces eloquent relationships from laravel 5.0 onwards. We all know, while we creating an application we all have foreign keys. Each table will be connected to some other. Eloquent make easy to connect each tables easily. Here we will One to one, one to many and many to many relationships. Here we will see three types of relationships,
   
. One to one relationships
    . One to many relationships
    . Many to many relationships

Why Eloquent Relationships

Here we have 2 tables, students and marks, so for join each table,

$student = student::join(‘marks’,’marks.student_id,’=’,students.id’)->where(‘students.id’,’1’)->get();

dd($student);



the above query is to long, so when we connect more tables its too tough we will be having a big query and complicated.



Model Query using Relationships


$student_marks = student::find(1);

dd($student_marks->mark1);



The above example is a simple example of eloquent relationships. We can reduce the first query into a simple one.





ONE TO ONE RELATIOSHIPS

Here we are creating 2 tables:
* Users
* Phones

Now we can see one to one relationships using hasone() and belongsto().

We need to create table using migrations



Create migrations


users table will be created by using


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

$table->increments('id');

$table->string('name');

$table->string('email')->unique();

$table->string('password');

$table->rememberToken();

$table->timestamps();

});


Phones table will be created by


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

$table->increments('id');

$table->integer('user_id')->unsigned();

$table->string('phone');

$table->timestamps();

$table->foreign('user_id')->references('id')->on('users')

->onDelete('cascade');

});



After that we need to create model for each tables, as we all know if the table name is laravel table name will be ending with ‘s’ and model name will be without ‘s’ of the same table name.



User model



<?php

namespace App;

use Illuminate\Notifications\Notifiable;

use Illuminate\Foundation\Auth\User as Authenticatable;



class User extends Authenticatable

{

use Notifiable;





protected $fillable = [

'name', 'email', 'password',

];





protected $hidden = [

'password', 'remember_token',

];





public function phone()

{

return $this->hasOne('App\Phone');

}

}



Phone Model



<?php

namespace App;

use Illuminate\Database\Eloquent\Model;



class Phone extends Model

{



public function user()

{

return $this->belongsTo('App\User');

}

}



For Creating records



$user = User::find(1);

$phone = new Phone;

$phone->phone = '9080054945';

$user->phone()->save($phone);



$phone = Phone::find(1);

$user = User::find(10);

$phone->user()->associate($user)->save();



Now we can get our records by


$phone = User::find(1)->phone;

dd($phone);



$user = Phone::find(1)->user;

dd($user);





ONE TO MANY RELATIONSHIPS

Here we will use hasMany() and belongsTo() for relationships

Now we are creating two tables, posts and comments, we will be having a foreign key towards posts table.


Migrations for posts and comments table


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

$table->increments('id');

$table->string("name");

$table->timestamps();

});



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

$table->increments('id');

$table->integer('post_id')->unsigned();

$table->string("comment");

$table->timestamps();

$table->foreign('post_id')->references('id')->on('posts')

->onDelete('cascade');

});



Now we will create Post Model and Comment Model



Post Model



<?php

namespace App;

use Illuminate\Database\Eloquent\Model;



class Post extends Model

{



public function comments()

{

return $this->hasMany(Comment::class);

}

}



Comment Model



<?php

namespace App;

use Illuminate\Database\Eloquent\Model;



class Comment extends Model

{



public function post()

{

return $this->belongsTo(Post::class);

}

}



Now we can create records


$post = Post::find(1);

$comment = new Comment;

$comment->comment = "Hi Harikrishnan";

$post = $post->comments()->save($comment);

$post = Post::find(1);



$comment1 = new Comment;

$comment1->comment = "How are You?";

$comment2 = new Comment;

$comment2->comment = "Where are you?";

$post = $post->comments()->saveMany([$comment1, $comment2]);



$comment = Comment::find(1);

$post = Post::find(2);

$comment->post()->associate($post)->save();



Now we can get records


$post = Post::find(1);

$comments = $post->comments;

dd($comments);



$comment = Comment::find(1);

$post = $comment->post;

dd($post);



MANY TO MANY RELATIONSHIPS

Many to many is little bit different and complicated than the above two.



In this example, I will create users, roles, and role, users_tables, here each table will be connected each other using the foreign keys.



Using belongsToMany() we will use see a demo of Many to many relationship



Create Migrations



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

$table->increments('id');

$table->string('name');

$table->string('email')->unique();

$table->string('password');

$table->rememberToken();

$table->timestamps();

});



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

$table->increments('id');

$table->string('name');

$table->timestamps();

});



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

$table->integer('user_id')->unsigned();

$table->integer('role_id')->unsigned();

$table->foreign('user_id')->references('id')->on('users')

->onDelete('cascade');

$table->foreign('role_id')->references('id')->on('roles')

->onDelete('cascade');

});



Create Models



User Model


<?php

namespace App;

use Illuminate\Notifications\Notifiable;

use Illuminate\Foundation\Auth\User as Authenticatable;



class User extends Authenticatable

{

use Notifiable;





protected $fillable = [

'name', 'email', 'password',

];





protected $hidden = [

'password', 'remember_token',

];





public function roles()

{

return $this->belongsToMany(Role::class, 'role_user');

}

}


Role Model


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;



class Role extends Model

{



public function users()

{

return $this->belongsToMany(User::class, 'role_user');

}

}


UserRole Model


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;



class UserRole extends Model

{

}



Now we can create records


$user = User::find(2); 

$roleIds = [1, 2];

$user->roles()->attach($roleIds);



$user = User::find(3);

$roleIds = [1, 2];

$user->roles()->sync($roleIds);



$role = Role::find(1);

$userIds = [10, 11];

$role->users()->attach($userIds);



$role = Role::find(2);

$userIds = [10, 11];

$role->users()->sync($userIds);



Now we can retrieve records


$user = User::find(1); 

dd($user->roles);



$role = Role::find(1);

dd($role->users);




Hence laravel Eloquent is more powerful and we do relationships easily compared to native query. We will be having three more relationships in laravel. Ie.., has many, one to many polymorphic and many to many polymorphic. With eloquent relationship we can easily connect the tables each other. One to one relationships we can connect two tables with their basic functionalities. In one to many we will connect with single table with multiple options. In Many to many we will be having more tables.

SPONSORS