Two years back we had published an article called create a RESTful Services using PHP, in that most the PHP methods got depreciated. I have been looking for a simple RESTful api framework in PHP, I found few lightweight frameworks called Slim and Epiphany. In this tutorial I had implement a sample user updates RESTful web services project using Slim framework in PHP, it is very simple to implement and only focused on RESTful.
Download Script Live Demo
The tutorial contains three folders called api, js and css with PHP files.
api
-- Slim // Slim Framework
---- db.php
---- index.php // api index file
---- .htaccess // url redirection file.
js
-- jquery.min.js
-- ajaxGetPost.js
css
-- style.css
index.html
-- Slim // Slim Framework
---- db.php
---- index.php // api index file
---- .htaccess // url redirection file.
js
-- jquery.min.js
-- ajaxGetPost.js
css
-- style.css
index.html
Database Design
To build the friend updates system, you have to create three tables such as Users, Friends and Updates. You can check my previous tutorials for friend system.
Users Table
User table contains all the users registration details. CREATE TABLE `users` (
`user_id` int(11) AUTO_INCREMENT,
`username` varchar(50),
`password` varchar(100),
`name` varchar(100),
`profile_pic` varchar(200),
PRIMARY KEY (`user_id`)
);
`user_id` int(11) AUTO_INCREMENT,
`username` varchar(50),
`password` varchar(100),
`name` varchar(100),
`profile_pic` varchar(200),
PRIMARY KEY (`user_id`)
);
Updates Table
User table contains user status update details. CREATE TABLE `updates` (
`update_id` int(11) AUTO_INCREMENT,
`user_update` text,
`user_id_fk` int(11),
`created` int(11),
`ip` varchar(50),
PRIMARY KEY (`update_id`)
);
`update_id` int(11) AUTO_INCREMENT,
`user_update` text,
`user_id_fk` int(11),
`created` int(11),
`ip` varchar(50),
PRIMARY KEY (`update_id`)
);
RESTful Web Services API using Java and MySQL
Slim Framework
api/index.php
Slim Framework helps you to implement API system simple.
<?php
require 'db.php';
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->get('/users','getUsers');
$app->get('/updates','getUserUpdates');
$app->post('/updates', 'insertUpdate');
$app->delete('/updates/delete/:update_id','deleteUpdate');
$app->get('/users/search/:query','getUserSearch');
$app->run();
// GET http://www.yourwebsite.com/api/users
function getUsers() {
$sql = "SELECT user_id,username,name,profile_pic FROM users ORDER BY user_id DESC";
try {
$db = getDB();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"users": ' . json_encode($users) . '}';
} catch(PDOException $e) {
//error_log($e->getMessage(), 3, '/var/tmp/phperror.log'); //Write error log
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// GET http://www.yourwebsite.com/api/updates
function getUserUpdates() {
$sql = "SELECT A.user_id, A.username, A.name, A.profile_pic, B.update_id, B.user_update, B.created FROM users A, updates B WHERE A.user_id=B.user_id_fk ORDER BY B.update_id DESC";
try {
$db = getDB();
$stmt = $db->prepare($sql);
$stmt->execute();
$updates = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"updates": ' . json_encode($updates) . '}';
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// DELETE http://www.yourwebsite.com/api/updates/delete/10
function deleteUpdate($update_id)
{
$sql = "DELETE FROM updates WHERE update_id=:update_id";
try {
$db = getDB();
$stmt = $db->prepare($sql);
$stmt->bindParam("update_id", $update_id);
$stmt->execute();
$db = null;
echo true;
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// POST http://www.yourwebsite.com/api/updates
function insertUpdate() {
//....
//....
}
function getUserUpdate($update_id) {
//.....
//.....
}
// GET http://www.yourwebsite.com/api/users/search/sri
function getUserSearch($query) {
//.....
//....
}
?>
require 'db.php';
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->get('/users','getUsers');
$app->get('/updates','getUserUpdates');
$app->post('/updates', 'insertUpdate');
$app->delete('/updates/delete/:update_id','deleteUpdate');
$app->get('/users/search/:query','getUserSearch');
$app->run();
// GET http://www.yourwebsite.com/api/users
function getUsers() {
$sql = "SELECT user_id,username,name,profile_pic FROM users ORDER BY user_id DESC";
try {
$db = getDB();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"users": ' . json_encode($users) . '}';
} catch(PDOException $e) {
//error_log($e->getMessage(), 3, '/var/tmp/phperror.log'); //Write error log
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// GET http://www.yourwebsite.com/api/updates
function getUserUpdates() {
$sql = "SELECT A.user_id, A.username, A.name, A.profile_pic, B.update_id, B.user_update, B.created FROM users A, updates B WHERE A.user_id=B.user_id_fk ORDER BY B.update_id DESC";
try {
$db = getDB();
$stmt = $db->prepare($sql);
$stmt->execute();
$updates = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"updates": ' . json_encode($updates) . '}';
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// DELETE http://www.yourwebsite.com/api/updates/delete/10
function deleteUpdate($update_id)
{
$sql = "DELETE FROM updates WHERE update_id=:update_id";
try {
$db = getDB();
$stmt = $db->prepare($sql);
$stmt->bindParam("update_id", $update_id);
$stmt->execute();
$db = null;
echo true;
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
// POST http://www.yourwebsite.com/api/updates
function insertUpdate() {
//....
//....
}
function getUserUpdate($update_id) {
//.....
//.....
}
// GET http://www.yourwebsite.com/api/users/search/sri
function getUserSearch($query) {
//.....
//....
}
?>
db.php
You have to modify database configuration details, before trying this enable php_pdo extension in php.ini file.
<?php
function getDB() {
$dbhost="localhost";
$dbuser="username";
$dbpass="password";
$dbname="database";
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
?>
function getDB() {
$dbhost="localhost";
$dbuser="username";
$dbpass="password";
$dbname="database";
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
?>
Chrome Extention
A Extention for testing PHP restful API response download here Advanced REST client Application
Cross Domain Access
A cross-domain system is transfer information/data between two or more differing domains. Eg. abc.com to xyz.com.htaccess
I did modified the Slim Framework default .htaccess code for cross domain support.
RewriteEngine On
# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
#
# RewriteBase /
# Cross domain access
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
#
# RewriteBase /
# Cross domain access
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
Learn more about Status Message Design with CSS
Jquery
Contains JavaScript and HTML code, using Jquery ajax parsing API data into HTML format.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="js/ajaxGetPost.js"></script>
<script>
$(document).ready(function()
{
var base_url="http://www.yourwebsite.com/project_name/";
var url,encodedata;
$("#update").focus();
/* Load Updates */
url=base_url+'api/updates';
ajax_data('GET',url, function(data)
{
$.each(data.updates, function(i,data)
{
var html="<div class='stbody' id='stbody"+data.update_id+"'><div class='stimg'><img src='"+data.profile_pic+"' class='stprofileimg'/></div><div class='sttext'><strong>"+data.name+"</strong>"+data.user_update+"<span id='"+data.update_id+"' class='stdelete'>Delete</span></div></div>";
$(html).appendTo("#mainContent");
});
});
/* Insert Update */
$('body').on("click",'.stpostbutton',function()
{
var update=$('#update').val();
encode=JSON.stringify({
"user_update": update,
"user_id": $('#user_id').val()
});
url=base_url+'api/updates';
if(update.length>0)
{
post_ajax_data(url,encode, function(data)
{
$.each(data.updates, function(i,data)
{
var html="<div class='stbody' id='stbody"+data.update_id+"'><div class='stimg'><img src='"+data.profile_pic+"' class='stprofileimg'/></div><div class='sttext'><strong>"+data.name+"</strong>"+data.user_update+"<span id='"+data.update_id+"' class='stdelete'>Delete</span></div></div>";
$("#mainContent").prepend(html);
$('#update').val('').focus();
});
});
}
});
/* Delete Updates */
$('body').on("click",'.stdelete',function()
{
var ID=$(this).attr("id");
url=base_url+'api/updates/delete/'+ID;
ajax_data('DELETE',url, function(data)
{
$("#stbody"+ID).fadeOut("slow");
});
});
});
</script>
<script src="js/ajaxGetPost.js"></script>
<script>
$(document).ready(function()
{
var base_url="http://www.yourwebsite.com/project_name/";
var url,encodedata;
$("#update").focus();
/* Load Updates */
url=base_url+'api/updates';
ajax_data('GET',url, function(data)
{
$.each(data.updates, function(i,data)
{
var html="<div class='stbody' id='stbody"+data.update_id+"'><div class='stimg'><img src='"+data.profile_pic+"' class='stprofileimg'/></div><div class='sttext'><strong>"+data.name+"</strong>"+data.user_update+"<span id='"+data.update_id+"' class='stdelete'>Delete</span></div></div>";
$(html).appendTo("#mainContent");
});
});
/* Insert Update */
$('body').on("click",'.stpostbutton',function()
{
var update=$('#update').val();
encode=JSON.stringify({
"user_update": update,
"user_id": $('#user_id').val()
});
url=base_url+'api/updates';
if(update.length>0)
{
post_ajax_data(url,encode, function(data)
{
$.each(data.updates, function(i,data)
{
var html="<div class='stbody' id='stbody"+data.update_id+"'><div class='stimg'><img src='"+data.profile_pic+"' class='stprofileimg'/></div><div class='sttext'><strong>"+data.name+"</strong>"+data.user_update+"<span id='"+data.update_id+"' class='stdelete'>Delete</span></div></div>";
$("#mainContent").prepend(html);
$('#update').val('').focus();
});
});
}
});
/* Delete Updates */
$('body').on("click",'.stdelete',function()
{
var ID=$(this).attr("id");
url=base_url+'api/updates/delete/'+ID;
ajax_data('DELETE',url, function(data)
{
$("#stbody"+ID).fadeOut("slow");
});
});
});
</script>
HTML Code
Contains HTML code. $("body").on('click','.stpostbutton', function(){}- stpostbutton is the ID name of the POST button. Using jquery stringify converting input data into JSON format.
<div>
<textarea id="update" class="stupdatebox"></textarea>
<input type="hidden" id="user_id" value="User Session Value">
<input type="submit" value="POST" class="stpostbutton">
</div>
<div id="mainContent"></div>
<textarea id="update" class="stupdatebox"></textarea>
<input type="hidden" id="user_id" value="User Session Value">
<input type="submit" value="POST" class="stpostbutton">
</div>
<div id="mainContent"></div>
ajaxGetPost.js
Jquery Post, Get and Delete Ajax functions.
//POST Ajax
function post_ajax_data(url, encodedata, success)
{
$.ajax({
type:"POST",
url:url,
data :encodedata,
dataType:"json",
restful:true,
contentType: 'application/json',
cache:false,
timeout:20000,
async:true,
beforeSend :function(data) { },
success:function(data){
success.call(this, data);
},
error:function(data){
alert("Error In Connecting");
}
});
}
//GET and DELETE Ajax
function ajax_data(type, url, success)
{
$.ajax({
type:type,
url:url,
dataType:"json",
restful:true,
cache:false,
timeout:20000,
async:true,
beforeSend :function(data) { },
success:function(data){
success.call(this, data);
},
error:function(data){
alert("Error In Connecting");
}
});
}
function post_ajax_data(url, encodedata, success)
{
$.ajax({
type:"POST",
url:url,
data :encodedata,
dataType:"json",
restful:true,
contentType: 'application/json',
cache:false,
timeout:20000,
async:true,
beforeSend :function(data) { },
success:function(data){
success.call(this, data);
},
error:function(data){
alert("Error In Connecting");
}
});
}
//GET and DELETE Ajax
function ajax_data(type, url, success)
{
$.ajax({
type:type,
url:url,
dataType:"json",
restful:true,
cache:false,
timeout:20000,
async:true,
beforeSend :function(data) { },
success:function(data){
success.call(this, data);
},
error:function(data){
alert("Error In Connecting");
}
});
}
I Love API's. Thank you for sharing this article. I will try to used it in my web application.
ReplyDeletegr8 work bro
ReplyDeletenice work .
ReplyDeletebut i need more explanation about Cross Domain Access where can i configure the domains and how
Thank you for sharing this article and very simple code
ReplyDeletebest regards
I love it.. I will try soon.
ReplyDeletegood one...
ReplyDeletei'll try it soon....
Hi.
ReplyDeleteI try run in local, but show me the next error:
Error In Connecting.
Please help me with this.. Thanks
Nice work.......
ReplyDeleteI will try to implement.
plis the ,htaccess is not working. is there any configure i need to do at the apache config
ReplyDeleteHi have implemented this on my localhost. It works fine. Finally one question in my mind why we use RESTfull service and when should we use it.
ReplyDeleteSpecially in the file /socialproject/api/index.php, we use $app->get() function. what is use of this? Please write down in brief.
Thanks;
Praveen Kumar
Very good work.
ReplyDeleteHello,
ReplyDeleteIt'll help us, well done bro.
Best Wishes for your future.
Great, Its very helpful tutorial
ReplyDeleteBut what about security point - authentication password/any key?
Please update your tutorial with API - authentication security point covered
How do we secure this API, that is important aspect, please cover that as mentioned by Jatin Gupta
ReplyDeleteThats great, And very useful post
ReplyDeleteThankx a lot.
how to do this REST API setup in CPANEL For this example with slim.
ReplyDeleteHi.
ReplyDeleteI try run in local, but show me the next error:
Error In Connecting.
Please help me with this.. Thanks
Just write(Copy and Paste) this code in .htaccess file
DeleteRewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
its nice script but i face a problem " when i run on my local server i face a error Internal Server Error "
ReplyDeleteand connection fail as alert
Everything working fine but delete api not working
ReplyDeleteError In Connecting // Ajax Delete
Error In Connecting // DELETE http://www.yourwebsite.com/api/updates/delete/10
Delete function not working please check it
whats the api for post cmd. meaning how can I insert using post
ReplyDeletehi,
ReplyDeleteI want to use this and post request
{
"user_update"="rddndher",
"user_id"="1"
}
but I'm not able to what should be request?
The delete is not working.. If you navigate to api/updates/delete/1
ReplyDeleteYou get a 404 error
great post
ReplyDeleteGreat post, can i get the POST function InsertUpdate pls????
ReplyDeleteIt can implement authentication?
ReplyDeleteHi.
ReplyDeleteI try run in localhost, but show me the next error:
Error In Connecting.
Please help me with this.. Thanks
very good article. thanks.!
ReplyDelete9lessons.info all article too good to understand.Excellent Site i did never see.
ReplyDeletehow to write function for multi array: like below given e.g.
ReplyDelete{
"name":"john",
"city":"pittsburgh",
"fav_things":[
{
"first_color":"blue",
"second_color":"green",
"third_color":"white"
},
{
"fourth_color":"black",
"fifth_color":"orange",
"sixth_color":"brown"
}
],
"active":true
}
Please reply with sample code if possible
nice post
ReplyDeleteNote that you've to have mod_headers installed in your apache server
ReplyDeleteA safer .htaccess to avoid error should be:
______________
# mandatory for the script to work
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
# RewriteBase /
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
___________
great tutorial !
thanks! ANDREA SOMOVIGO.
ReplyDeleteNice Bro keep sharing :)
ReplyDeleteThanks for the nice tutorial.
ReplyDeleteI am getting error:-
ReplyDeleteError in connection.
no any url is working.
Enable mod_rewrite extension for PHP
DeleteVery Nice and easily you explain api.Thanks for Awesome Share.
Deletehai bro,
ReplyDeletekindly teach me how to install slimframework, installing it makes a huge headache.
Hi, I need create an function to download some images. How do it?
ReplyDeleteHello Srinivas, Thanks a lot for this tutorial. After so many trys and days, I found this tutorial that worked on first time.
ReplyDeleteThe post is not working. I get {UPDATE: }{"error":{"text":SQLSTATE[HY093]: Invalid parameter number: parameter was not defined}}
In my table, I have category_id (Auto incre), category_name, categoy_isparent (tinyint), category_desc fields. This is my insert function ;
$request = \Slim\Slim::getInstance()->request();
$update = json_decode($request->getBody());
echo '{UPDATE: ' . $update .'}';
//$sql = "INSERT INTO category (category_name, categoy_isparent, category_description) VALUES (:category_name, :categoy_isparent, :category_description)";
$sql = "INSERT INTO category (category_name, categoy_isparent, category_description) VALUES (:categoryName, :isparent, :desc)";
try {
$db = getDB();
$stmt = $db->prepare($sql);
//$stmt->bindParam('sis', $update->category_name, $isparent, $desc);
$stmt->bindParam("categoryName", $update->categoryName);
$desc = "Descriptions";
$isparent = 1;
$stmt->bindParam("isparent", $isparent);
$stmt->bindParam("$desc", $desc);
//$stmt->bindParam("category_description", $update->category_description);
//$time=time();
//$stmt->bindParam("categoy_isparent", $update->categoy_isparent);
//$ip=$_SERVER['REMOTE_ADDR'];
$stmt->execute();
$update->id = $db->lastInsertId();
$db = null;
$update_id= $update->id;
//getUserUpdate($update_id);
if ($stmt->errno) {
echo "FAILURE!!! " . $stmt->error;
}
else
echo '{"Inserted ": {"Id": '. $update_id .'}}';
//echo "Updated {$stmt->affected_rows} rows";
$stmt->close();
} catch(PDOException $e) {
//error_log($e->getMessage(), 3, '/var/tmp/php.log');
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
It just gives the above error. I want to add desc also in parameters only. And initially, isparent will be true only (default value).
Can you please help me with this. I tried a lot, but couldn't figure out. Please help me.
Thanks
Replace
Delete$stmt->bindParam("$desc", $desc);
to
$stmt->bindParam("desc", $desc);
Thanks for pointing that mistake. But it seems that the prolem is something else. I still get the response -
Delete{UPDATE: }{"error":{"text":SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'category_name' cannot be null}}
I gave params - "categoryName" value "Khaas baat"
You see the echo of "Update", shouldn't the value of $update contain the parameter categoryName ???
Hello Srinivas,
ReplyDeleteThank you so much for posting this great stuff!
I am creating login and dashboard then i want to add api links on dashboard. How i can access html design/view in dashboard please guide me.
Regards
Hi Srinivas,
ReplyDeleteyour post is wonderful, however i am getting 404 error when passing parameter in URl DELETE http://www.yourwebsite.com/api/updates/delete/10
rest r working , i am using php7 & slim3 , any idea will really appreciate.
Regards
Anupam
Rest api working as fine in localhost but not in godaddy server, did'nt get any responses
ReplyDeleteHi Srinivas, how can I use middleware in ur example code structure..?
ReplyDeleteHi Srinivas, I have to insert 10 users, I have this data inn array, Now i want to insert it without using loop. There is a function insert_batch() in Codeigniter which does this. Do U know such type of function in SLIM...? PLEASE REPLY..
ReplyDeleteThanks Srinivas for your coding. But when i try to run on localhost i'm getting "Internal Server Error" and I've enabled the rewrite module.
ReplyDeleteFolder name is same as "SocialProject" and accessed as http://localhost/SocialProject/api/updates/
was not working. Kindly help me.
Enable PHP mod_rewrite extension for .htaccess support
Deletethank you for your sample
ReplyDeleteerror in connecting
ReplyDeletealert box shown
what should i do ?
i alredy make a .htaccess file
how to paginate using this rest slim framework?
ReplyDeleteTry to send a post parameter with page. Check this article https://www.9lessons.info/2017/11/ionic-infinite-scrolling-angular-restful.html
DeleteIts not working with php 7.x, I got 404 when I hit the api, same url works in php 5.x
ReplyDeleteDo you have any solution ?
What I did is I created API with php 5.x and them moved to server with is in 7.x
Make sure enable mod_rewrite extension for PHP 7.0. For reference check XAMPP configuration settings.
DeleteAny idea SRINIVAS TAMADA for Slim4 that same like this RESTful services using Slim PHP Framework thank you in advance
ReplyDelete