PHP & Web Development Blogs

Search Results For: application
Showing 11 to 15 of 25 blog articles.
4715 views · 1 years ago

Conferences are always looking for speakers - it can be hard to keep track of them all and the requirements they have. I wanted to put together this quick guide to make it easy for you to apply. Make sure to apply because as Wayne Gretzky said “You miss 100% of the shots you don’t take”!!!

![](https://sayingimages.com/wp-content/uploads/you-can-do-it-if-you-do-it-meme.jpg)

## phpDay 2019

First we have phpDay 2019 which will take place on May 10 & 11 at Hotel San Marco in Verona, Italy. Some facts about this call for papers:

* **Submission deadline:** February 4, 2019

* **Submit via:** https://cfp.phpday.it/

* For more info on the conference: https://2019.phpday.it/

* Twitter: (@phpday)

* Speaker package includes: Full conference pass (jsDay + phpDay), speaker dinner the first night, lunch, reception and activities included in regular conference.

* For speakers remote to the Area: A refund of up to €200 for travel costs (or €500 from US or extra-EU), 2 complimentary hotel nights (+1 hotel night for speakers presenting multiple talks or US/extra-EU) and Taxi fare from/to the airport.

* **In Submission**: make sure your talk title and abstract define the exact topic you want to talk about and what you hope people will learn from the session.

* **Talk Ideas**: APIs (REST, SOAP, etc.), Architectures, Continuous Delivery, Databases, Development, Devops, Frameworks, Internals, PHP 7.x / PHP 8, Security, Testing and UI/UX.

## ScotlandPHP

Next we have ScotlandPHP which will take place on November 8 & 9 at Edinburgh International Conference Centre in Edinburgh, Scotland.

* **Submission deadline:** April 22, 2019

* **Submit via:** https://cfs.scotlandphp.co.uk/

* For more info on the conference: https://conference.scotlandphp.co.uk/

* Twitter: (@scotlandphp)

* Speaker package: Full conference pass, lunch, receptions and activities included in regular conference.

* For speakers remote to the Area: Complimentary airfare/travel, 2 complimentary hotel nights and we'll pick you up and drop you off to/from the airport so you don't have to worry about it.

* Speakers will be provided with a projector, a wireless lapel microphone and a screen for their presentation (size depends on the room). Speakers should bring any equipment they need to connect to projectors (VGA). It is also suggested that you reduce your dependency on the in-house internet connection as possible. We will however provide HDMI and Mini Display Port connections for all speakers on request. If you need something different or your selected talk needs audio equipment just let us know. We'll work it out.

* Looking for talks and workshops (November 8th).

* **Talk Ideas**: Virtualization and environments, Javascript, Alternate PHP run-times, PHP internals, Development principles, Security, Mobile-first design, Testing (unit, functional, etc.), Version control, User Experience/Usability, Building APIs (REST, SOAP, whatever), Continuous Integration, Framework-related topics, and Professional development.

## Global diversity CFP day

In 2019 there will be numerous workshops hosted around the globe encouraging and advising newbie speakers to put together your very first talk proposal and share your own individual perspective on any subject of interest to people in tech.

* Twitter: (@gdcfpday)

* **Save the Date**: March 2, 2019

* **Register here**: https://www.globaldiversitycfpday.com/?utm_source=scotphp

## CoderCruise

Then there is CoderCruise which will take place on August 19-23. It's a cruise that takes off from Port Canaveral, Florida and goes to the Bahamas.

* Twitter: (@codercruise)

* **Submission deadline**: March 3, 2019

* **Submit via**: https://www.papercall.io/codercruise-2019

* For more info on the conference: https://www.codercruise.com/

* This is a polyglot conference so looking for speakers on a wide variety of languages (PHP, JavaScript, Java, Python, etc.) and on various tech topics.

## PHP Conference Asia 2019

There is also PHP Conference Asia 2019, which will take place on June 24-25 at Microsot Singapore.

* **Submission deadline**: March 8, 2019

* **Submit via:** https://cfp.phpconf.asia/

* For more info on the conference: https://2019.phpconf.asia/

* Twitter: (@PHPConfAsia)

* Speaker package includes: Speaker package: Full conference pass, lunch, receptions and activities included in regular conference. We'll pick you up and drop you off to/from the airport so you don't have to worry about it. Speakers' dinner on the first evening of the conference (24th June 2019). Transport to and from the conference venue will be included

* For speakers remote to the Area: 2 complimentary hotel nights and

we can consider providing grants to partially cover the air-fare for speakers who might have financial difficulties. This is on a case-by-case basis.

* Speakers will be provided with a projector, a wireless hand-held microphone and a screen for their presentation. Speakers should prepare their slides in 4x3 aspect ratio. Speakers should bring any equipment they need to connect to projectors (HDMI). It is also suggested that you reduce your dependency on the in-house internet connection as possible.

* **In Submission**: Make sure your talk title and abstract define the exact topic you want to talk about and what you hope people will learn from the session.

* **Talk Ideas**: Virtualization and environments, Javascript, Alternate PHP run-times, PHP internals, Development principles, Security, Mobile-first design, Testing (unit, functional, etc.), Version control, User Experience/Usability, Building APIs (REST, SOAP, whatever), Continuous Integration, Framework-related topics, and Professional development.

## Cascadia PHP

Another conference to apply to is Cascadia PHP, which will take place on September 19-21 at University Place Hotel & Conference Center in Portland, Oregon.

* **Submission deadline**: April 15, 2019

* **Submit via:** https://cfp.cascadiaphp.com/

* For more info on the conference: https://www.cascadiaphp.com/venue

* Twitter: (@CascadiaPHP)

* Speaker package includes: Speaker package: Full conference pass, lunch, receptions and activities included in regular conference. * For speakers remote to the Area: Complimentary airfare/travel, 2 complimentary hotel nights and we'll pick you up and drop you off to/from the airport so you don't have to worry about it.

* Speakers will be provided with a projector, a wireless lapel microphone and a screen for their presentation (size depends on the room). Speakers should bring any equipment they need to connect to projectors (VGA). It is also suggested that you reduce your dependency on the in-house internet connection as possible.

* **In Submission**: make sure your talk title and abstract define the exact topic you want to talk about and what you hope people will learn from the session.

* **Talk Ideas**: PHP internals, Version control, Framework-related topics, Building APIs (REST, SOAP, whatever), Mobile-first design, Professional development, Testing (unit, functional, etc.), Alternate PHP run-times, Development principles, Continuous Integration, Getting involved in the PHP community, User Experience/Usability, Technology at large, Security, Connecting to Different APIs, Development Tools, Virtualization and environments, Javascript, Modern hosting practices, Language Features, Databases, Refactoring legacy applications, Running/contributing to open source projects, AI and AR, and User Groups.

## Nomad PHP

Last but not least - this is an ongoing call for papers. This is perfect if you want to present from the comfort of your office, home or really wherever you are. It’s via RingCentral meetings and will be live and recorded. This is for none other than Nomad PHP.

* Twitter: (@nomadphp)

* Deadline: Anytime :D

* Talk length: 45 - 60 minutes.

* Talks should be unique to Nomad PHP and not available in video format online.

* Talk should not be recorded or made available elsewhere online for at least 3 months following your talk.

* The talk will be featured on our page and promoted via social media.

* Speakers will receive a financial stipend.

* Upon being selected we will reach out with further details.

* **Talk ideas**: AI & Machine Learning, APIs, Containerization, Databases, DevOps, Documentation, Frameworks, Performance, Security, Serverless, Testing, Tools, Upgrading/ Modernization, and more.

* **Submit here**: https://www.papercall.io/nomadphp

Now that you have some information - make sure to apply to all of these options! Can't wait to see all of your awesome talks you present :D!

8174 views · 1 years ago

![Create Simple RESTful APIs using PHP & MySQL](https://images.ctfassets.net/vzl5fkwyme3u/5s6X92LpF8dGGVZEnXGRK0/387bfe60541987d308e8201ca5bb5d3f/api_blog_post.png?w=1000)

Hi Guys,

I am sharing you the way to create simple resful apis using php and mysql. We are creating 2 apis here

First is to Loggin a existing user and second is to get list of written blogs by logged in user.

#### Create any database, i am taking ```news``` as the database name here, After it create following 2 tables inside it.

```

CREATE TABLE `users` (

`id` int(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,

`name` varchar(100),

`email` varchar(100),

`password` varchar(100),

`createdAt` datetime NOT NULL,

`updatedAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

);

CREATE TABLE `blogs` (

`id` int(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,

`user_id` int(11),

`title` varchar(255),

`summary` Tinytext,

`body` Text,

`createdAt` datetime NOT NULL,

`updatedAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

);

```

#### Now putting some dummy data to read via the api

```

--create 2 entries in users table--

INSERT INTO `news`.`users` (`id`, `name`, `email`, `password`, `createdAt`, `updatedAt`) VALUES (1, 'jeetendra singh', '[email protected]', MD5('123456'), '2018-12-28 02:05:12', CURRENT_TIMESTAMP), (2, 'Manvik Singh chaudhary', '[email protected]', MD5('654321'), '2018-12-28 03:08:11', CURRENT_TIMESTAMP);

-- create 2 blogs by userid 1--

INSERT INTO `news`.`blogs` (`id`, `user_id`, `title`, `summary`, `body`, `createdAt`, `updatedAt`) VALUES (1, '1', 'Blog title 1 by jeetendra', 'Blog summary 1 by jeetendra', 'Blog body 1 by jeetendra', '2018-12-28 02:00:00', CURRENT_TIMESTAMP), (2, '1', 'Blog Title 2 by jeetendra ', 'Blog summary 2 by jeetendra ', 'Blog body 2 by jeetendra ', '2018-12-28 05:10:21', CURRENT_TIMESTAMP);

-- create 2 blogs by userid 2

INSERT INTO `news`.`blogs` (`id`, `user_id`, `title`, `summary`, `body`, `createdAt`, `updatedAt`) VALUES (3, '2', 'Blog title 1 by manvik', 'Blog summary 1 by manvik', 'Blog body 1 by manvik', '2018-12-28 02:00:00', CURRENT_TIMESTAMP), (4, '2', 'Blog Title 2 by manvik ', 'Blog summary 2 by manvik ', 'Blog body 2 by manvik ', '2018-12-28 05:10:21', CURRENT_TIMESTAMP);

```

#### After creating this create a index.php and put this code for Db connection, login and get all blog method

```

<?php

header("Content-Type: application/json; charset=UTF-8");

class DBClass {

private $host = "localhost";

private $username = "root";

private $password = ""; / /set your passwrd here

private $database = "news";

public $connection;

/ / get the database connection

public function connect(){

$this->connection = null;

try{

$this->connection = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->database, $this->username, $this->password);

$this->connection->exec("set names utf8");

}catch(PDOException $exception){

echo "Error: " . $exception->getMessage();

}

return $this->connection;

}

public function login($email,$password){

if($this->connection==null)

{

$this->connect();

}

$query = "SELECT id,name,email,createdAt,updatedAt from users where email= ? and password= ?";

$stmt = $this->connection->prepare($query);

$stmt->execute(array($email,md5($password)));

$ret= $stmt->fetchAll(PDO::FETCH_ASSOC);

return $ret;

}

public function get_all_blogs($Uid){

if($this->connection==null)

{

$this->connect();

}

$query = "SELECT b.*,u.id as Uid,u.email as Uemail,u.name as Uname from blogs b join users u on u.id=b.user_id where b.user_id= ?";

$stmt = $this->connection->prepare($query);

$stmt->execute(array($Uid));

$ret= $stmt->fetchAll(PDO::FETCH_ASSOC);

return $ret;

}

public function response($array)

{

echo json_encode($array);

exit;

}

}

/ /recieve the requests here / /

$return=array();

$obj = new DBClass();

if(isset($_GET['action']) && $_GET['action']!='')

{

if($_GET['action']=="login")

{

if(isset($_POST['email']) && isset($_POST['password']))

{

$UserData=$obj->login($_POST['email'],$_POST['password']);

if(count($UserData)>0)

{

$return['status']=1;

$return['_data_']=$UserData[0];

$return['message']='User Logged in Successfully.';

}

else

{

$return['status']=0;

$return['message']='Error:Invalid Email or Password!';

}

}

else

{

$return['status']=0;

$return['message']='Error:Email or Password not provided!';

}

}

elseif($_GET['action']=="UserBlogs")

{

if(isset($_POST['Uid']))

{

$blogs=$obj->get_all_blogs($_POST['Uid']);

if(count($blogs)>0)

{

$return['status']=1;

$return['_data_']=$blogs;

$return['message']='Success.';

}

else

{

$return['status']=0;

$return['message']='Error:Invalid UserId!';

}

}

else

{

$return['status']=0;

$return['message']='Error:User Id not provided!';

}

}

}

else

{

$return['status']=0;

$return['message']='Error:Action not provided!';

}

$obj->response($return);

$obj->connection=null;

?>

```

#### Now api file is set, just make the urls pretty(readable form) using .htaccess file, put following code in it

```

RewriteEngine On

RewriteRule ^api/(.*) index.php?action=$1

```

#### Now your Simple Restful Apis are ready to use, Now Let me show you the postman screenshot where i have used these apis.

**Login Api Call:**

![LOGIN API CALL](https://www.w3school.info/blogimages/login_api.png)

**User Post/Blog Api Call**

![USER BLOGS](https://www.w3school.info/blogimages/UserBlogs_api.png)

4397 views · 1 years ago

![Create Alarm and Monitoring on Custom Memory and Disk Metrics for Amazon EC2](https://images.ctfassets.net/vzl5fkwyme3u/2HgdCq2lZucMyuiYyYiQie/b7376c29a2f94799613e8c1cb8ff4d3b/AdobeStock_91111530.jpeg?w=1000)

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

```ssh

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:**

```ssh

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

```ssh

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:

```ssh

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.

```ssh

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

```ssh

./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:**

```ssh

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:**

```ssh

*/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:

```ssh

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

![](https://4.bp.blogspot.com/-dYiNgtv5t4Q/XB-Kw76S49I/AAAAAAAAExM/DKKgzPUmVPUNpDqb0c57sVd3DjhY_3O6wCLcBGAs/s1600/aws.jpg)

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

![](https://3.bp.blogspot.com/-3OxSPmHahYc/XB-MhlaGSAI/AAAAAAAAExY/d9UIOFakcGAOADlbNOyd75r0Vkl5GtOfwCLcBGAs/s1600/aws2.jpg)

![](https://2.bp.blogspot.com/-Urfud3sv5LA/XB-My0O-qXI/AAAAAAAAExg/1isOeglXYyoS3U0u2uhwJN8ddhtnoHUwACLcBGAs/s1600/aws3.jpg)

![](https://2.bp.blogspot.com/-tXU4ieWKKdo/XB-NDrArsII/AAAAAAAAExo/7oz3qQZ7GrMETiJwWJdK75_hJ0qfADLvgCLcBGAs/s1600/aws4.jpg)

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

![](https://3.bp.blogspot.com/-Vu0WoCCP_5o/XB-NiKGzmSI/AAAAAAAAExw/IPBX8ir-97Q_Q6L6Ajq2vNpukYGN8BB_QCLcBGAs/s1600/aws5.jpg)

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

14882 views · 1 years ago

![Creating a URL shortener application in PHP & MySQL](https://images.ctfassets.net/vzl5fkwyme3u/3OjKfmylv2k8eWayqeCUWG/6d8e996fc7c757135df7fdd322fd50a4/AdobeStock_65694631.jpeg?w=1000)

Hi Guys,

In this post we will learn how to create your URL shortening application in PHP and MySQL.

You may also use this app as an API by calling the URLs from another application.

## Step 1: Creating a Table

```mysql

CREATE TABLE IF NOT EXISTS `url_shorten` (

`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,

`url` tinytext NOT NULL,

`short_code` varchar(50) NOT NULL,

`hits` int(11) NOT NULL,

`added_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

```

## Step 2: Create a file `index.php` and add database credentials in it

```php

$servername = 'localhost';

$username = 'root';

$password = ''; / /on localhost by default there is no password

$dbname = 'shorten_db';

$base_url='http://localhost/myapp/'; / / it is your application url

```

## Step 3: Get the URL in querystring and return a shortened URL using following code:

```php

if(isset($_GET['url']) && $_GET['url']!="")

{

$url=urldecode($_GET['url']);

if (filter_var($url, FILTER_VALIDATE_URL))

{

/ / Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

/ / Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}

$slug=GetShortUrl($url);

$conn->close();

echo $base_url.$slug;

}

else

{

die("$url is not a valid URL");

}

}

else

{ / /show the basic html form having element url

?>

<center>

<h1>Put Your Url Here</h1>

<form>

<p><input style="width:500px" type="url" name="url" required /></p>

<p><input type="submit" /></p>

</form>

</center>

<?php

}

```

Now we'll create a function called `GetShortUrl` for creating the short URL:

```php

function GetShortUrl($url){

global $conn;

$query = "SELECT * FROM url_shorten WHERE url = '".$url."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

$row = $result->fetch_assoc();

return $row['short_code'];

} else {

$short_code = generateUniqueID();

$sql = "INSERT INTO url_shorten (url, short_code, hits)

VALUES ('".$url."', '".$short_code."', '0')";

if ($conn->query($sql) === TRUE) {

return $short_code;

} else {

die("Unknown Error Occured");

}

}

}

```

The above function is using the `generateUniqueID()` function to generate a unique id for long urls. We can generate and retrieve the unique ID like so:

```php

function generateUniqueID(){

global $conn;

$token = substr(md5(uniqid(rand(), true)),0,6); / / creates a 6 digit unique short id

$query = "SELECT * FROM url_shorten WHERE short_code = '".$token."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

generateUniqueID();

} else {

return $token;

}

}

```

## Step 4

Now your code is ready to generate a unique short code for long URLs, but we still need to setup the redirection. When redirecting it should also increase a pageview/ hits in the table and then redirect to the longer, original URL.

Here is the code that allows us to do this:

```php

if(isset($_GET['redirect']) && $_GET['redirect']!="")

{

$slug=urldecode($_GET['redirect']);

/ / Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

/ / Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}

$url= GetRedirectUrl($slug);

$conn->close();

header("location:".$url);

exit;

}

```

This code uses a function called `GetRedirectUrl()` that we need to define, like so:

```php

function GetRedirectUrl($slug){

global $conn;

$query = "SELECT * FROM url_shorten WHERE short_code = '".addslashes($slug)."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

$row = $result->fetch_assoc();

/ / increase the hit

$hits=$row['hits']+1;

$sql = "update url_shorten set hits='".$hits."' where id='".$row['id']."' ";

$conn->query($sql);

return $row['url'];

}

else

{

die("Invalid Link!");

}

}

```

## Step 5

You are almost done now! If you don't want to use the redirect parameter in url for redirection purpose you will need to create a `.htaccess` file in your project and add following code:

```php

RewriteEngine on

RewriteRule ^([a-z0-9]{6})$ index.php?redirect=$1 [L]

```

### And You Have done it!

Now if you want to convert any url to short url just pass the url in get param of index.php like following:

http://localhost/myapp/?url=http://www.google.com **or** http://localhost/myapp/index.php?url=http://www.google.com **or** just open http://localhost/myapp/ **or** http://localhost/myapp/index.php,

It will show a html form where you may input any URL and click submit.

After submitting form or hitting the url with param url then it will print a shortened URL on screen. You may use that URL in new tab and see the url will be redirect to long URL and increase a Hit/ Pageview in MySQL table.

## Please find the full code for index.php here:

```php

<?php

$servername = 'localhost';

$username = 'root';

$password = ''; / / on localhost by default there is no password

$dbname = 'shorten_db';

$base_url='http://localhost/myapp/'; / / it is your application url

if(isset($_GET['url']) && $_GET['url']!="")

{

$url=urldecode($_GET['url']);

if (filter_var($url, FILTER_VALIDATE_URL))

{

/ / Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

/ / Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}

$slug=GetShortUrl($url);

$conn->close();

echo $base_url.$slug;

}

else

{

die("$url is not a valid URL");

}

}

else

{

?>

<center>

<h1>Put Your Url Here</h1>

<form>

<p><input style="width:500px" type="url" name="url" required /></p>

<p><input type="submit" /></p>

</form>

</center>

<?php

}

function GetShortUrl($url){

global $conn;

$query = "SELECT * FROM url_shorten WHERE url = '".$url."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

$row = $result->fetch_assoc();

return $row['short_code'];

} else {

$short_code = generateUniqueID();

$sql = "INSERT INTO url_shorten (url, short_code, hits)

VALUES ('".$url."', '".$short_code."', '0')";

if ($conn->query($sql) === TRUE) {

return $short_code;

} else {

die("Unknown Error Occured");

}

}

}

function generateUniqueID(){

global $conn;

$token = substr(md5(uniqid(rand(), true)),0,6); / / creates a 6 digit unique short id

$query = "SELECT * FROM url_shorten WHERE short_code = '".$token."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

generateUniqueID();

} else {

return $token;

}

}

if(isset($_GET['redirect']) && $_GET['redirect']!="")

{

$slug=urldecode($_GET['redirect']);

/ / Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

/ / Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}

$url= GetRedirectUrl($slug);

$conn->close();

header("location:".$url);

exit;

}

function GetRedirectUrl($slug){

global $conn;

$query = "SELECT * FROM url_shorten WHERE short_code = '".addslashes($slug)."' ";

$result = $conn->query($query);

if ($result->num_rows > 0) {

$row = $result->fetch_assoc();

/ / increase the hit

$hits=$row['hits']+1;

$sql = "update url_shorten set hits='".$hits."' where id='".$row['id']."' ";

$conn->query($sql);

return $row['url'];

}

else

{

die("Invalid Link!");

}

}

```

4066 views · 1 years ago

![Working With Thin Controller And Fat Model Concept In Laravel](https://images.ctfassets.net/vzl5fkwyme3u/18L41PfcrcYYkM0qAsCous/7caca26b8cfb5a643d8cb16b14ae5eae/AdobeStock_147870533.jpeg?w=1000)

Models and controllers are one of the most essential programming handlers in the Laravel MVC framework, and both are used vastly for different functional operations. Models in Laravel are created inside the app folder and are mostly used to interact with the database using Eloquent ORM, while the controllers are located inside the directory App/Http/Controllers.

As a programmer, you should have the knowledge how to keep the balance in between the programming usage of Models and controllers. As which one should be more utilized for allowing functional tasks in applications deployed on any [PHP MySQL hosting](https://www.cloudways.com/en/php-cloud-hosting.php).

## What is the Concept of Thin Controller and FAT Models

The concept of the thin controller and fat model is that we do less work in our controllers and more work in our models. Like we use our controllers to validate our data and then pass it to the models. While in models, we define our actual functional logic and main coding operations of the desired application. This code structuring process is also a very basic concept of MVC and also the differentiating factor from the conventional complex programming which we mistakenly ignore sometimes.

## Why FAT Controllers Are Bad For Handling Code

Controllers are always meant to be defined short and concise, and it should only be used for receiving requests and return responses to it. Anything else further should be programmed in Models, which is actually made for main functional operations.

Placing functional logic in controllers can be bad for many reasons for your applications deployed on any _hosting for PHP_. As it not only makes code structure long but also makes it complex sometimes. Further placing code in Controllers is also not recommended because if same functionality is needed somewhere else in route, then pulling out the whole code from their becomes difficult and so its reusability in the application.

Though Laravel is an MVC framework while developing on laravel, we sometimes ignore this and write mostly all our code including the extending of App\Model and all our functional logic in controller route methods. What we can do here is we can create a sub model of our parent model. For example, our parent model is User then we can create another sub model of username in CustomerModel if you are using the same User model for all types of users. In this model, we will write all the logic related to user type Customer.

So now let's take an example of my existing blog creating comment system with laravel and vuejs. In that article, you can see I have made so much mess in my controller methods. Mostly, I have written all my comments logic in my methods, so to shorten that let's clean them in this article. Inside app folder, I will create a new file with name CommentModel.php. Inside this file, I will write my whole logic for comment functions. This is my basic file:

```php

<?php

namespace App;

use App\Comment;

use App\CommentVote;

use App\CommentSpam;

use App\User;

use Auth;

class CommentModel

{

}

?>

```

Right now it contains no function but has the reference of all my models which I required for this model. Let's first add a function named **getallcomments** passing **$pageId** as a parameter inside it. The function will get all the comments for the given page:

```php

public function getAllComments($pageId)

{

$comments = Comment::where('page_id',$pageId)->get();

$commentsData = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$replies = $this->replies($key->id);

$photo = $user->first()->photo_url;

/ / dd($photo->photo_url);

$reply = 0;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if(Auth::user()){

$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

if($voteByUser){

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if($spamComment){

$spam = 1;

}

}

if(sizeof($replies) > 0){

$reply = 1;

}

if(!$spam){

array_push($commentsData,[

"name" => $name,

"photo_url" => (string)$photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"reply" => $reply,

"votedByUser" =>$vote,

"vote" =>$voteStatus,

"spam" => $spam,

"replies" => $replies,

"date" => $key->created_at->toDateTimeString()

]);

}

}

$collection = collect($commentsData);

return $collection->sortBy('votes');

}

```

Now I will create another function named **replies** which takes **$commentId** as a parameter. The function is more or less programmed in the same manner as the upper function get all comments.

```php

protected function replies($commentId)

{

$comments = Comment::where('reply_id',$commentId)->get();

$replies = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$photo = $user->first()->photo_url;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if(Auth::user()){

$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

if($voteByUser){

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if($spamComment){

$spam = 1;

}

}

if(!$spam){

array_push($replies,[

"name" => $name,

"photo_url" => $photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"votedByUser" => $vote,

"vote" => $voteStatus,

"spam" => $spam,

"date" => $key->created_at->toDateTimeString()

]);

}

}

$collection = collect($replies);

return $collection->sortBy('votes');

}

```

Now lets create a function **create comment **which passes **$array** as a parameter in it:

```php

public function createComment($arary)

{

$comment = Comment::create($array);

if($comment)

return [ "status" => "true","commentId" => $comment->id ];

else

return [ "status" => "false" ];

}

```

Similarly, Now I will create all the function for comment in my **CommentModel**, so that all the functions gets accumulated in one model.

```php

<?php

namespace App;

use App\Comment;

use App\CommentSpam;

use App\CommentVote;

use App\User;

use Auth;

class CommentModel

{

public function getAllComments($pageId)

{

$comments = Comment::where('page_id', $pageId)->get();

$commentsData = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$replies = $this->replies($key->id);

$photo = $user->first()->photo_url;

/ / dd($photo->photo_url);

$reply = 0;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if (Auth::user()) {

$voteByUser = CommentVote::where('comment_id', $key->id)->where('user_id', Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id', $key->id)->where('user_id', Auth::user()->id)->first();

if ($voteByUser) {

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if ($spamComment) {

$spam = 1;

}

}

if (sizeof($replies) > 0) {

$reply = 1;

}

if (!$spam) {

array_push($commentsData, [

"name" => $name,

"photo_url" => (string) $photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"reply" => $reply,

"votedByUser" => $vote,

"vote" => $voteStatus,

"spam" => $spam,

"replies" => $replies,

"date" => $key->created_at->toDateTimeString(),

]);

}

}

$collection = collect($commentsData);

return $collection->sortBy('votes');

}

protected function replies($commentId)

{

$comments = Comment::where('reply_id', $commentId)->get();

$replies = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$photo = $user->first()->photo_url;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if (Auth::user()) {

$voteByUser = CommentVote::where('comment_id', $key->id)->where('user_id', Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id', $key->id)->where('user_id', Auth::user()->id)->first();

if ($voteByUser) {

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if ($spamComment) {

$spam = 1;

}

}

if (!$spam) {

array_push($replies, [

"name" => $name,

"photo_url" => $photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"votedByUser" => $vote,

"vote" => $voteStatus,

"spam" => $spam,

"date" => $key->created_at->toDateTimeString(),

]);

}

}

$collection = collect($replies);

return $collection->sortBy('votes');

}

public function createComment($arary)

{

$comment = Comment::create($array);

if ($comment) {

return ["status" => "true", "commentId" => $comment->id];

} else {

return ["status" => "false"];

}

}

public function voteComment($commentId, $array)

{

$comments = Comment::find($commentId);

$data = [

"comment_id" => $commentId,

'vote' => $array->vote,

'user_id' => $array->users_id,

];

if ($array->vote == "up") {

$comment = $comments->first();

$vote = $comment->votes;

$vote++;

$comments->votes = $vote;

$comments->save();

}

if ($array->vote == "down") {

$comment = $comments->first();

$vote = $comment->votes;

$vote--;

$comments->votes = $vote;

$comments->save();

}

if (CommentVote::create($data)) {

return true;

}

}

public function spamComment($commentId, $array)

{

$comments = Comment::find($commentId);

$comment = $comments->first();

$spam = $comment->spam;

$spam++;

$comments->spam = $spam;

$comments->save();

$data = [

"comment_id" => $commentId,

'user_id' => $array->users_id,

];

if (CommentSpam::create($data)) {

return true;

}

}

}

?>

```

Now we have all our required methods in **CommentModel**. So now let's clean up **CommentController** which is currently bit complex and lengthy in code structure. As right now **CommentController **look like this:

```php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use App\Comment;

use App\CommentVote;

use App\CommentSpam;

use App\User;

use Auth;

class CommentController extends Controller

{

/ **

* Get Comments for pageId

*

* @return Comments

*/

public function index($pageId)

{

/ /

$comments = Comment::where('page_id',$pageId)->get();

$commentsData = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$replies = $this->replies($key->id);

$photo = $user->first()->photo_url;

/ / dd($photo->photo_url);

$reply = 0;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if(Auth::user()){

$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

if($voteByUser){

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if($spamComment){

$spam = 1;

}

}

if(sizeof($replies) > 0){

$reply = 1;

}

if(!$spam){

array_push($commentsData,[

"name" => $name,

"photo_url" => (string)$photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"reply" => $reply,

"votedByUser" =>$vote,

"vote" =>$voteStatus,

"spam" => $spam,

"replies" => $replies,

"date" => $key->created_at->toDateTimeString()

]);

}

}

$collection = collect($commentsData);

return $collection->sortBy('votes');

}

protected function replies($commentId)

{

$comments = Comment::where('reply_id',$commentId)->get();

$replies = [];

foreach ($comments as $key) {

$user = User::find($key->users_id);

$name = $user->name;

$photo = $user->first()->photo_url;

$vote = 0;

$voteStatus = 0;

$spam = 0;

if(Auth::user()){

$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

if($voteByUser){

$vote = 1;

$voteStatus = $voteByUser->vote;

}

if($spamComment){

$spam = 1;

}

}

if(!$spam){

array_push($replies,[

"name" => $name,

"photo_url" => $photo,

"commentid" => $key->id,

"comment" => $key->comment,

"votes" => $key->votes,

"votedByUser" => $vote,

"vote" => $voteStatus,

"spam" => $spam,

"date" => $key->created_at->toDateTimeString()

]);

}

}

$collection = collect($replies);

return $collection->sortBy('votes');

}

/ **

* Store a newly created resource in storage.

*

* @param \Illuminate\Http\Request $request

* @return \Illuminate\Http\Response

*/

public function store(Request $request)

{

$this->validate($request, [

'comment' => 'required',

'reply_id' => 'filled',

'page_id' => 'filled',

'users_id' => 'required',

]);

$comment = Comment::create($request->all());

/ / dd($comment);

if($comment)

return [ "status" => "true","commentId" => $comment->id ];

}

/ **

* Update the specified resource in storage.

*

* @param \Illuminate\Http\Request $request

* @param $commentId

* @param $type

* @return \Illuminate\Http\Response

*/

public function update(Request $request, $commentId,$type)

{

if($type == "vote"){

$this->validate($request, [

'vote' => 'required',

'users_id' => 'required',

]);

$comments = Comment::find($commentId);

$data = [

"comment_id" => $commentId,

'vote' => $request->vote,

'user_id' => $request->users_id,

];

if($request->vote == "up"){

$comment = $comments->first();

$vote = $comment->votes;

$vote++;

$comments->votes = $vote;

$comments->save();

}

if($request->vote == "down"){

$comment = $comments->first();

$vote = $comment->votes;

$vote--;

$comments->votes = $vote;

$comments->save();

}

if(CommentVote::create($data))

return "true";

}

if($type == "spam"){

$this->validate($request, [

'users_id' => 'required',

]);

$comments = Comment::find($commentId);

$comment = $comments->first();

$spam = $comment->spam;

$spam++;

$comments->spam = $spam;

$comments->save();

$data = [

"comment_id" => $commentId,

'user_id' => $request->users_id,

];

if(CommentSpam::create($data))

return "true";

}

}

/ **

* Remove the specified resource from storage.

*

* @param int $id

* @return \Illuminate\Http\Response

*/

public function destroy($id)

{

/ /

}

}?>

```

After cleaning up the controller it will look much simpler and easy to understand like this:

```php

<?php

namespace App\Http\Controllers;

use App\CommentModel;

use Illuminate\Http\Request;

class CommentController extends Controller

{

private $commentModel = null;

private function __construct()

{

$this->commentModel = new CommentModel();

}

/ **

* Get Comments for pageId

*

* @return Comments

*/

public function index($pageId)

{

return $this->commentModel->getAllComments($pageId);

}

/ **

* Store a newly created resource in storage.

*

* @param \Illuminate\Http\Request $request

* @return \Illuminate\Http\Response

*/

public function store(Request $request)

{

$this->validate($request, [

'comment' => 'required',

'reply_id' => 'filled',

'page_id' => 'filled',

'users_id' => 'required',

]);

return $this->commentModel->createComment($request->all());

}

/ **

* Update the specified resource in storage.

*

* @param \Illuminate\Http\Request $request

* @param $commentId

* @param $type

* @return \Illuminate\Http\Response

*/

public function update(Request $request, $commentId, $type)

{

if ($type == "vote") {

$this->validate($request, [

'vote' => 'required',

'users_id' => 'required',

]);

return $this->commentModel->voteComment($commentId, $request->all());

}

if ($type == "spam") {

$this->validate($request, [

'users_id' => 'required',

]);

return $this->commentModel->spamComment($commentId, $request->all());

}

}

}

?>

```

## Wrap Up!

So Isn't it looking much cleaner and simpler to understand now? This is what actually a thin controller and fat model looks like. We have all our logic related to Comment system programmed in our **CommentModel **and our controller is now just used to transfer data from the user to our model and returning the response which is coming from our model.

So this is how the structuring of the thin controller and fat model is made. Give your thoughts in the comments below.

SPONSORS

Faster PHP Cloud Hosting