PHP & Web Development Blogs

Search Results For: system
Showing 16 to 20 of 33 blog articles.
8413 views · 3 years ago
Laravel Eloquent Relationship Part 2

As you all know, Laravel Eloquent Relationships are powerful and easy methods introduced by Laravel for helping developers to reduce the complexity when connecting with multiple tables. While connecting with multiple tables, this method is very easy for developers for creating the application

Here you can see the next three methods of the eloquent relationships:
   
. Has Many Through Relationship
    . One to Many Polymorphic
    . Many to many Polymorphic

HAS MANY THROUGH ELOQUENT RELATIONSHIP

Has many through is a little bit complicated while understanding. I will provide a shortcut method to provide access data of another mode relationship. We will create a user table, post table, and country table and they will be interconnected with each other.

Here we will see Many through relationship will use hasManyThrough() for the relation


Create Migrations


Users table

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

$table->increments('id');

$table->string('name');

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

$table->string('password');

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

$table->rememberToken();

$table->timestamps();

$table->foreign('country_id')->references('id')->on('countries')

->onDelete('cascade');

});


Posts table

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

$table->increments('id');

$table->string("name");

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

$table->timestamps();

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

->onDelete('cascade');

});


Countries table

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

$table->increments('id');

$table->string('name');

$table->timestamps();

});


Create Models


Country Model

<?php


namespace App;

use Illuminate\Database\Eloquent\Model;


class Country extends Model

{

public function posts(){

return $this->hasManyThrough(

Post::class,

User::class,

'country_id',
'user_id',
'id',
'id'
);

}

}


Now we can retrieve records by

$country = Country::find(1); 

dd($country->posts);


ONE TO MANY POLYMORPHIC RELATIONSHIP

One to many polymorphic relationships used one model belongs to another model on a single file. For example, we will have tweets and blogs, both having the comment system. So we need to add the comments. Then we can manage both in a single table


Here we will use sync with a pivot table, create records, get all data, delete, update, and everything related to one too many relationships.

Now I will show one too many polymorphic will use morphMany() and morphTo() for relation.


Create Migrations

Posts table

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

$table->increments('id');

$table->string("name");

$table->timestamps();

});

Videos Table

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

$table->increments('id');

$table->string("name");

$table->timestamps();

});

Comments Table

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

$table->increments('id');

$table->string("body");

$table->integer('commentable_id');

$table->string("commentable_type");

$table->timestamps();

});


Create Models

Post Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;


class Post extends Model

{



public function comments(){

return $this->morphMany(Comment::class, 'commentable');

}

}

Video Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;


class Video extends Model{



public function comments(){

return $this->morphMany(Comment::class, 'commentable');

}

}

Comment Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model{



public function commentable(){

return $this->morphTo();

}

}


Create Records


$post = Post::find(1); 

$comment = new Comment;

$comment->body = "Hi Harikrishnan";

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


$video = Video::find(1);

$comment = new Comment;

$comment->body = "Hi Harikrishnan";

$video->comments()->save($comment);



Now we can retrieve records


$post = Post::find(1); 

dd($post->comments);



$video = Video::find(1);

dd($video->comments);



MANY TO MANY POLYMORPHIC RELATIONSHIPS

Many to many polymorphic is also a little bit complicated like above. If we have a tweet, video and tag table, we need to connect each table like every tweet and video will have multiple persons to tag. And for each and every tag there will be multiple tweet or videos.

Here we can understand the creating of many to many polymorphic relationships, with a foreign key schema of one to many relationships, use sync with a pivot table, create records, attach records, get all records, delete, update, where condition and etc..


Here morphToMany() and morphedByMany() will be used for many to many polymorphic relationships

Creating Migrations

Posts Table

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

$table->increments('id');

$table->string("name");

$table->timestamps();

});

Videos Table

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

$table->increments('id');

$table->string("name");

$table->timestamps();

});

Tags table

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

$table->increments('id');

$table->string("name");

$table->timestamps();

});

Taggables table

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

$table->integer("tag_id");

$table->integer("taggable_id");

$table->string("taggable_type");

});


Creating ModelsPost Model


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model

{



public function tags(){

return $this->morphToMany(Tag::class, 'taggable');

}

}


Video Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model

{



public function tags(){

return $this->morphToMany(Tag::class, 'taggable');

}

}

Tag Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model

{



public function posts(){

return $this->morphedByMany(Post::class, 'taggable');

}





public function videos(){

return $this->morphedByMany(Video::class, 'taggable');

}

}

Creating Records

$post = Post::find(1); 
$tag = new Tag;
$tag->name = "Hi Harikrishnan";
$post->tags()->save($tag);


$video = Video::find(1);
$tag = new Tag;
$tag->name = "Vishnu";
$video->tags()->save($tag);


$post = Post::find(1);
$tag1 = new Tag;
$tag1->name = "Kerala Blasters";
$tag2 = new Tag;
$tag2->name = "Manajapadda";
$post->tags()->saveMany([$tag1, $tag2]);


$video = Video::find(1);
$tag1 = new Tag;
$tag1->name = "Kerala Blasters";
$tag2 = new Tag;
$tag2->name = "Manajappada";
$video->tags()->saveMany([$tag1, $tag2]);


$post = Post::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$post->tags()->attach([$tag1->id, $tag2->id]);


$video = Video::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$video->tags()->attach([$tag1->id, $tag2->id]);


$post = Post::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$post->tags()->sync([$tag1->id, $tag2->id]);


$video = Video::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$video->tags()->sync([$tag1->id, $tag2->id]);



Now we can retrieve records

$post = Post::find(1); 
dd($post->tags);


$video = Video::find(1);
dd($video->tags)


$tag = Tag::find(1);
dd($tag->posts);


$tag = Tag::find(1);
dd($tag->videos);



Hence we completed all the relationships. In the above blog how has many through relationship, one to many polymorphic relationships and many to many polymorphic are working. This feature is introduced from Laravel 5.0 onwards and till the current version. Without the model, we can’t able to do this relationship. If we are using an eloquent relationship it will be very useful while developing an application.
7770 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];
}


}

?>

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

6340 views · 5 years ago
Oprah: You Get Extension! Everyone Get Extension!

Ever wanted to publish your own extension for PHP but stopped by the lack of C language background? Well, maybe it's time for another take. Zephir language is targeted at people like you.

If you follow this link, you will find these words that say a lot about this project:

Zephir, an open source, high-level language designed to ease the creation and

maintainability of extensions for PHP with a focus on type and memory safety.

Its syntax highly resembles that of PHP, only there's no dollars scattered around your code. Dollar signs, I mean, the PHP $variables. You only can create object oriented extensions, and all the classes written in Zephir must be namespaced. A different and stricter type system exists in Zephir, which allows for transpiling the code you write, into a real C extension.

Why would you need it? This question is largely answered here: Why Zephir. I can only add that, from experience, if you expect a crazy performance boost, you probably won't get it. First, most of the time the bottleneck is not PHP but the IO: database interactions, network and filesystem interactions etc. You won't gain anything by switching to different programming language, in that regards. However, some CPU-intensive calculations may run a lot faster, and if you worry about someone stealing you intellectual property - it also might be worth checking out, because then you can ship your software in form of a binary.

Zephir is the language in which the fastest modern PHP framework is written - Phalcon. Whether or not to use it - decide for yourself, it obviously has its pros and cons. But it's certainly interesting to know that you have the ability to approach some of your tasks completely differently!

See you around, and feel free to comment!
6151 views · 5 years ago
Press Release

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

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.

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, or sharing the service with your friends.

SPONSORS