Datatables server side using PHP and MYSQL

 

 

 

 

 

 overview:

Hello, today we will talk about how to use the server side in

the Datatables  using PHP and MYSQL in simple steps.

  files structure:

 

 

datatables.sql:  import data to mysql database .

index.php:  main page .

server_side.php: The main code to handle Datatables server-side.

ssp.class.php:  library for dealing with databases compatible with Datatables server side.  

Step1 : import  my data to  database.

datatables.sql:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


 
-- --------------------------------------------------------

--
-- بنية الجدول `datatables_demo`
--

CREATE TABLE `datatables_demo` (
  `firstname` varchar(255) NOT NULL,
  `lastname` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- إرجاع أو استيراد بيانات الجدول `datatables_demo`
--

INSERT INTO `datatables_demo` (`firstname`, `lastname`, `email`, `id`) VALUES
('firstname0', 'lastname0', 'email0@gmail.com', 1),
('firstname1', 'lastname1', 'email1@gmail.com', 2),
('firstname2', 'lastname2', 'email2@gmail.com', 3),
('firstname3', 'lastname3', 'email3@gmail.com', 4),
('firstname4', 'lastname4', 'email4@gmail.com', 5),
('firstname5', 'lastname5', 'email5@gmail.com', 6),
('firstname6', 'lastname6', 'email6@gmail.com', 7),
('firstname7', 'lastname7', 'email7@gmail.com', 8),
('firstname8', 'lastname8', 'email8@gmail.com', 9),
('firstname9', 'lastname9', 'email9@gmail.com', 10),
('firstname10', 'lastname10', 'email10@gmail.com', 11),
('firstname11', 'lastname11', 'email11@gmail.com', 12),
('firstname12', 'lastname12', 'email12@gmail.com', 13),
('firstname13', 'lastname13', 'email13@gmail.com', 14),
('firstname14', 'lastname14', 'email14@gmail.com', 15),
('firstname15', 'lastname15', 'email15@gmail.com', 16),
('firstname16', 'lastname16', 'email16@gmail.com', 17),
('firstname17', 'lastname17', 'email17@gmail.com', 18),
('firstname18', 'lastname18', 'email18@gmail.com', 19),
('firstname19', 'lastname19', 'email19@gmail.com', 20),
('firstname20', 'lastname20', 'email20@gmail.com', 21),
('firstname21', 'lastname21', 'email21@gmail.com', 22),
('firstname22', 'lastname22', 'email22@gmail.com', 23),
('firstname23', 'lastname23', 'email23@gmail.com', 24),
('firstname24', 'lastname24', 'email24@gmail.com', 25),
('firstname25', 'lastname25', 'email25@gmail.com', 26),
('firstname26', 'lastname26', 'email26@gmail.com', 27),
('firstname27', 'lastname27', 'email27@gmail.com', 28),
('firstname28', 'lastname28', 'email28@gmail.com', 29),
('firstname29', 'lastname29', 'email29@gmail.com', 30),
('firstname30', 'lastname30', 'email30@gmail.com', 31),
('firstname31', 'lastname31', 'email31@gmail.com', 32),
('firstname32', 'lastname32', 'email32@gmail.com', 33),
('firstname33', 'lastname33', 'email33@gmail.com', 34),
('firstname34', 'lastname34', 'email34@gmail.com', 35),
('firstname35', 'lastname35', 'email35@gmail.com', 36),
('firstname36', 'lastname36', 'email36@gmail.com', 37),
('firstname37', 'lastname37', 'email37@gmail.com', 38),
('firstname38', 'lastname38', 'email38@gmail.com', 39),
('firstname39', 'lastname39', 'email39@gmail.com', 40),
('firstname40', 'lastname40', 'email40@gmail.com', 41),
('firstname41', 'lastname41', 'email41@gmail.com', 42),
('firstname42', 'lastname42', 'email42@gmail.com', 43),
('firstname43', 'lastname43', 'email43@gmail.com', 44),
('firstname44', 'lastname44', 'email44@gmail.com', 45),
('firstname45', 'lastname45', 'email45@gmail.com', 46),
('firstname46', 'lastname46', 'email46@gmail.com', 47),
('firstname47', 'lastname47', 'email47@gmail.com', 48),
('firstname48', 'lastname48', 'email48@gmail.com', 49),
('firstname49', 'lastname49', 'email49@gmail.com', 50),
('firstname50', 'lastname50', 'email50@gmail.com', 51),
('firstname51', 'lastname51', 'email51@gmail.com', 52),
('firstname52', 'lastname52', 'email52@gmail.com', 53),
('firstname53', 'lastname53', 'email53@gmail.com', 54),
('firstname54', 'lastname54', 'email54@gmail.com', 55),
('firstname55', 'lastname55', 'email55@gmail.com', 56),
('firstname56', 'lastname56', 'email56@gmail.com', 57),
('firstname57', 'lastname57', 'email57@gmail.com', 58),
('firstname58', 'lastname58', 'email58@gmail.com', 59),
('firstname59', 'lastname59', 'email59@gmail.com', 60),
('firstname60', 'lastname60', 'email60@gmail.com', 61),
('firstname61', 'lastname61', 'email61@gmail.com', 62),
('firstname62', 'lastname62', 'email62@gmail.com', 63),
('firstname63', 'lastname63', 'email63@gmail.com', 64),
('firstname64', 'lastname64', 'email64@gmail.com', 65),
('firstname65', 'lastname65', 'email65@gmail.com', 66),
('firstname66', 'lastname66', 'email66@gmail.com', 67),
('firstname67', 'lastname67', 'email67@gmail.com', 68),
('firstname68', 'lastname68', 'email68@gmail.com', 69),
('firstname69', 'lastname69', 'email69@gmail.com', 70),
('firstname70', 'lastname70', 'email70@gmail.com', 71),
('firstname71', 'lastname71', 'email71@gmail.com', 72),
('firstname72', 'lastname72', 'email72@gmail.com', 73),
('firstname73', 'lastname73', 'email73@gmail.com', 74),
('firstname74', 'lastname74', 'email74@gmail.com', 75),
('firstname75', 'lastname75', 'email75@gmail.com', 76),
('firstname76', 'lastname76', 'email76@gmail.com', 77),
('firstname77', 'lastname77', 'email77@gmail.com', 78),
('firstname78', 'lastname78', 'email78@gmail.com', 79),
('firstname79', 'lastname79', 'email79@gmail.com', 80),
('firstname80', 'lastname80', 'email80@gmail.com', 81),
('firstname81', 'lastname81', 'email81@gmail.com', 82),
('firstname82', 'lastname82', 'email82@gmail.com', 83),
('firstname83', 'lastname83', 'email83@gmail.com', 84),
('firstname84', 'lastname84', 'email84@gmail.com', 85),
('firstname85', 'lastname85', 'email85@gmail.com', 86),
('firstname86', 'lastname86', 'email86@gmail.com', 87),
('firstname87', 'lastname87', 'email87@gmail.com', 88),
('firstname88', 'lastname88', 'email88@gmail.com', 89),
('firstname89', 'lastname89', 'email89@gmail.com', 90),
('firstname90', 'lastname90', 'email90@gmail.com', 91),
('firstname91', 'lastname91', 'email91@gmail.com', 92),
('firstname92', 'lastname92', 'email92@gmail.com', 93),
('firstname93', 'lastname93', 'email93@gmail.com', 94),
('firstname94', 'lastname94', 'email94@gmail.com', 95),
('firstname95', 'lastname95', 'email95@gmail.com', 96),
('firstname96', 'lastname96', 'email96@gmail.com', 97),
('firstname97', 'lastname97', 'email97@gmail.com', 98),
('firstname98', 'lastname98', 'email98@gmail.com', 99),
('firstname99', 'lastname99', 'email99@gmail.com', 100),
('firstname100', 'lastname100', 'email100@gmail.com', 101),
('firstname101', 'lastname101', 'email101@gmail.com', 102),
('firstname102', 'lastname102', 'email102@gmail.com', 103),
('firstname103', 'lastname103', 'email103@gmail.com', 104),
('firstname104', 'lastname104', 'email104@gmail.com', 105),
('firstname105', 'lastname105', 'email105@gmail.com', 106),
('firstname106', 'lastname106', 'email106@gmail.com', 107),
('firstname107', 'lastname107', 'email107@gmail.com', 108),
('firstname108', 'lastname108', 'email108@gmail.com', 109),
('firstname109', 'lastname109', 'email109@gmail.com', 110),
('firstname110', 'lastname110', 'email110@gmail.com', 111),
('firstname111', 'lastname111', 'email111@gmail.com', 112),
('firstname112', 'lastname112', 'email112@gmail.com', 113),
('firstname113', 'lastname113', 'email113@gmail.com', 114),
('firstname114', 'lastname114', 'email114@gmail.com', 115),
('firstname115', 'lastname115', 'email115@gmail.com', 116),
('firstname116', 'lastname116', 'email116@gmail.com', 117),
('firstname117', 'lastname117', 'email117@gmail.com', 118),
('firstname118', 'lastname118', 'email118@gmail.com', 119),
('firstname119', 'lastname119', 'email119@gmail.com', 120),
('firstname120', 'lastname120', 'email120@gmail.com', 121),
('firstname121', 'lastname121', 'email121@gmail.com', 122),
('firstname122', 'lastname122', 'email122@gmail.com', 123),
('firstname123', 'lastname123', 'email123@gmail.com', 124),
('firstname124', 'lastname124', 'email124@gmail.com', 125),
('firstname125', 'lastname125', 'email125@gmail.com', 126),
('firstname126', 'lastname126', 'email126@gmail.com', 127),
('firstname127', 'lastname127', 'email127@gmail.com', 128),
('firstname128', 'lastname128', 'email128@gmail.com', 129),
('firstname129', 'lastname129', 'email129@gmail.com', 130),
('firstname130', 'lastname130', 'email130@gmail.com', 131),
('firstname131', 'lastname131', 'email131@gmail.com', 132),
('firstname132', 'lastname132', 'email132@gmail.com', 133),
('firstname133', 'lastname133', 'email133@gmail.com', 134),
('firstname134', 'lastname134', 'email134@gmail.com', 135),
('firstname135', 'lastname135', 'email135@gmail.com', 136),
('firstname136', 'lastname136', 'email136@gmail.com', 137),
('firstname137', 'lastname137', 'email137@gmail.com', 138),
('firstname138', 'lastname138', 'email138@gmail.com', 139),
('firstname139', 'lastname139', 'email139@gmail.com', 140),
('firstname140', 'lastname140', 'email140@gmail.com', 141),
('firstname141', 'lastname141', 'email141@gmail.com', 142),
('firstname142', 'lastname142', 'email142@gmail.com', 143),
('firstname143', 'lastname143', 'email143@gmail.com', 144),
('firstname144', 'lastname144', 'email144@gmail.com', 145),
('firstname145', 'lastname145', 'email145@gmail.com', 146),
('firstname146', 'lastname146', 'email146@gmail.com', 147),
('firstname147', 'lastname147', 'email147@gmail.com', 148),
('firstname148', 'lastname148', 'email148@gmail.com', 149),
('firstname149', 'lastname149', 'email149@gmail.com', 150),
('firstname150', 'lastname150', 'email150@gmail.com', 151),
('firstname151', 'lastname151', 'email151@gmail.com', 152),
('firstname152', 'lastname152', 'email152@gmail.com', 153),
('firstname153', 'lastname153', 'email153@gmail.com', 154),
('firstname154', 'lastname154', 'email154@gmail.com', 155),
('firstname155', 'lastname155', 'email155@gmail.com', 156),
('firstname156', 'lastname156', 'email156@gmail.com', 157),
('firstname157', 'lastname157', 'email157@gmail.com', 158),
('firstname158', 'lastname158', 'email158@gmail.com', 159),
('firstname159', 'lastname159', 'email159@gmail.com', 160),
('firstname160', 'lastname160', 'email160@gmail.com', 161),
('firstname161', 'lastname161', 'email161@gmail.com', 162),
('firstname162', 'lastname162', 'email162@gmail.com', 163),
('firstname163', 'lastname163', 'email163@gmail.com', 164),
('firstname164', 'lastname164', 'email164@gmail.com', 165),
('firstname165', 'lastname165', 'email165@gmail.com', 166),
('firstname166', 'lastname166', 'email166@gmail.com', 167),
('firstname167', 'lastname167', 'email167@gmail.com', 168),
('firstname168', 'lastname168', 'email168@gmail.com', 169),
('firstname169', 'lastname169', 'email169@gmail.com', 170),
('firstname170', 'lastname170', 'email170@gmail.com', 171),
('firstname171', 'lastname171', 'email171@gmail.com', 172),
('firstname172', 'lastname172', 'email172@gmail.com', 173),
('firstname173', 'lastname173', 'email173@gmail.com', 174),
('firstname174', 'lastname174', 'email174@gmail.com', 175),
('firstname175', 'lastname175', 'email175@gmail.com', 176),
('firstname176', 'lastname176', 'email176@gmail.com', 177),
('firstname177', 'lastname177', 'email177@gmail.com', 178),
('firstname178', 'lastname178', 'email178@gmail.com', 179),
('firstname179', 'lastname179', 'email179@gmail.com', 180),
('firstname180', 'lastname180', 'email180@gmail.com', 181),
('firstname181', 'lastname181', 'email181@gmail.com', 182),
('firstname182', 'lastname182', 'email182@gmail.com', 183),
('firstname183', 'lastname183', 'email183@gmail.com', 184),
('firstname184', 'lastname184', 'email184@gmail.com', 185),
('firstname185', 'lastname185', 'email185@gmail.com', 186),
('firstname186', 'lastname186', 'email186@gmail.com', 187),
('firstname187', 'lastname187', 'email187@gmail.com', 188),
('firstname188', 'lastname188', 'email188@gmail.com', 189),
('firstname189', 'lastname189', 'email189@gmail.com', 190),
('firstname190', 'lastname190', 'email190@gmail.com', 191),
('firstname191', 'lastname191', 'email191@gmail.com', 192),
('firstname192', 'lastname192', 'email192@gmail.com', 193),
('firstname193', 'lastname193', 'email193@gmail.com', 194),
('firstname194', 'lastname194', 'email194@gmail.com', 195),
('firstname195', 'lastname195', 'email195@gmail.com', 196),
('firstname196', 'lastname196', 'email196@gmail.com', 197),
('firstname197', 'lastname197', 'email197@gmail.com', 198);

--
-- Indexes for dumped tables
--

--
-- Indexes for table `user`
--
ALTER TABLE `datatables_demo`
  ADD PRIMARY KEY (`id`);

-- 
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `user`
--
ALTER TABLE `datatables_demo`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=199;
COMMIT;
 

 


Step2 : We put the main code on this page.

index.php:

<!doctype html>
 <html lang="en">

 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta name="description" content="">
   <meta name="generator" content="Hugo 0.72.0">
   <title>server-side-datatable</title>

   <!-- datatable css  -->
   <link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css" />

   <!-- Bootstrap core CSS -->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
   <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
   <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
 </head>

 <body style="background-color:#fdfdfd;">
   <br>
   <h1 align="center" style="color:color(srgb 0.52 0.59 0.7);font-weight:bold;">Datatables server side processing  with PHP and MYSQL </h1>
   <br>
   <div class="container">
     <table id="example" class="display" style="width:100%">
       <thead>
         <tr>
           <th>First name</th>
           <th>Last name</th>
           <th>email</th>
           
         </tr>
       </thead>

     </table>
   </div>

   <!-- datatable js -->
   <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
   <script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>

   <script type="text/javascript">
     $(document).ready(function() {
       $('#example').DataTable({
         "searching": true,
         "processing": true,
         "serverSide": true,
         "ajax": "server_side.php"
       });
     });
   </script>
 </body>

 </html>

Step3 : code of ssp.class.php libirary.

ssp.class.php:

 <?php

/*
 * Helper functions for building a DataTables server-side processing SQL query
 *
 * The static functions in this class are just helper functions to help build
 * the SQL used in the DataTables demo server-side processing scripts. These
 * functions obviously do not represent all that can be done with server-side
 * processing, they are intentionally simple to show how it works. More complex
 * server-side processing operations will likely require a custom script.
 *
 * See http://datatables.net/usage/server-side for full details on the server-
 * side processing requirements of DataTables.
 *
 * @license MIT - http://datatables.net/license_mit
 */


// Please Remove below 4 lines as this is use in Datatatables test environment for your local or live environment please remove it or else it will not work
$file = $_SERVER['DOCUMENT_ROOT'].'/datatables/pdo.php';
if ( is_file( $file ) ) {
    include( $file );
}


class SSP {
    /**
     * Create the data output array for the DataTables rows
     *
     *  @param  array $columns Column information array
     *  @param  array $data    Data from the SQL get
     *  @return array          Formatted data in a row based format
     */
    static function data_output ( $columns, $data )
    {
        $out = array();

        for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
            $row = array();

            for ( $j=0, $jen=count($columns) ; $j<$jen ; $j++ ) {
                $column = $columns[$j];

                // Is there a formatter?
                if ( isset( $column['formatter'] ) ) {
                    if(empty($column['db'])){
                        $row[ $column['dt'] ] = $column['formatter']( $data[$i] );
                    }
                    else{
                        $row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );
                    }
                }
                else {
                    if(!empty($column['db'])){
                        $row[ $column['dt'] ] = $data[$i][ $columns[$j]['db'] ];
                    }
                    else{
                        $row[ $column['dt'] ] = "";
                    }
                }
            }

            $out[] = $row;
        }

        return $out;
    }


    /**
     * Database connection
     *
     * Obtain an PHP PDO connection from a connection details array
     *
     *  @param  array $conn SQL connection details. The array should have
     *    the following properties
     *     * host - host name
     *     * db   - database name
     *     * user - user name
     *     * pass - user password
     *  @return resource PDO connection
     */
    static function db ( $conn )
    {
        if ( is_array( $conn ) ) {
            return self::sql_connect( $conn );
        }

        return $conn;
    }


    /**
     * Paging
     *
     * Construct the LIMIT clause for server-side processing SQL query
     *
     *  @param  array $request Data sent to server by DataTables
     *  @param  array $columns Column information array
     *  @return string SQL limit clause
     */
    static function limit ( $request, $columns )
    {
        $limit = '';

        if ( isset($request['start']) && $request['length'] != -1 ) {
            $limit = "LIMIT ".intval($request['start']).", ".intval($request['length']);
        }

        return $limit;
    }


    /**
     * Ordering
     *
     * Construct the ORDER BY clause for server-side processing SQL query
     *
     *  @param  array $request Data sent to server by DataTables
     *  @param  array $columns Column information array
     *  @return string SQL order by clause
     */
    static function order ( $request, $columns )
    {
        $order = '';

        if ( isset($request['order']) && count($request['order']) ) {
            $orderBy = array();
            $dtColumns = self::pluck( $columns, 'dt' );

            for ( $i=0, $ien=count($request['order']) ; $i<$ien ; $i++ ) {
                // Convert the column index into the column data property
                $columnIdx = intval($request['order'][$i]['column']);
                $requestColumn = $request['columns'][$columnIdx];

                $columnIdx = array_search( $requestColumn['data'], $dtColumns );
                $column = $columns[ $columnIdx ];

                if ( $requestColumn['orderable'] == 'true' ) {
                    $dir = $request['order'][$i]['dir'] === 'asc' ?
                        'ASC' :
                        'DESC';

                    $orderBy[] = '`'.$column['db'].'` '.$dir;
                }
            }

            if ( count( $orderBy ) ) {
                $order = 'ORDER BY '.implode(', ', $orderBy);
            }
        }

        return $order;
    }


    /**
     * Searching / Filtering
     *
     * Construct the WHERE clause for server-side processing SQL query.
     *
     * NOTE this does not match the built-in DataTables filtering which does it
     * word by word on any field. It's possible to do here performance on large
     * databases would be very poor
     *
     *  @param  array $request Data sent to server by DataTables
     *  @param  array $columns Column information array
     *  @param  array $bindings Array of values for PDO bindings, used in the
     *    sql_exec() function
     *  @return string SQL where clause
     */
    static function filter ( $request, $columns, &$bindings )
    {
        $globalSearch = array();
        $columnSearch = array();
        $dtColumns = self::pluck( $columns, 'dt' );

        if ( isset($request['search']) && $request['search']['value'] != '' ) {
            $str = $request['search']['value'];

            for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
                $requestColumn = $request['columns'][$i];
                $columnIdx = array_search( $requestColumn['data'], $dtColumns );
                $column = $columns[ $columnIdx ];

                if ( $requestColumn['searchable'] == 'true' ) {
                    if(!empty($column['db'])){
                        $binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
                        $globalSearch[] = "`".$column['db']."` LIKE ".$binding;
                    }
                }
            }
        }

        // Individual column filtering
        if ( isset( $request['columns'] ) ) {
            for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
                $requestColumn = $request['columns'][$i];
                $columnIdx = array_search( $requestColumn['data'], $dtColumns );
                $column = $columns[ $columnIdx ];

                $str = $requestColumn['search']['value'];

                if ( $requestColumn['searchable'] == 'true' &&
                 $str != '' ) {
                    if(!empty($column['db'])){
                        $binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
                        $columnSearch[] = "`".$column['db']."` LIKE ".$binding;
                    }
                }
            }
        }

        // Combine the filters into a single string
        $where = '';

        if ( count( $globalSearch ) ) {
            $where = '('.implode(' OR ', $globalSearch).')';
        }

        if ( count( $columnSearch ) ) {
            $where = $where === '' ?
                implode(' AND ', $columnSearch) :
                $where .' AND '. implode(' AND ', $columnSearch);
        }

        if ( $where !== '' ) {
            $where = 'WHERE '.$where;
        }

        return $where;
    }


    /**
     * Perform the SQL queries needed for an server-side processing requested,
     * utilising the helper functions of this class, limit(), order() and
     * filter() among others. The returned array is ready to be encoded as JSON
     * in response to an SSP request, or can be modified if needed before
     * sending back to the client.
     *
     *  @param  array $request Data sent to server by DataTables
     *  @param  array|PDO $conn PDO connection resource or connection parameters array
     *  @param  string $table SQL table to query
     *  @param  string $primaryKey Primary key of the table
     *  @param  array $columns Column information array
     *  @return array          Server-side processing response array
     */
    static function simple ( $request, $conn, $table, $primaryKey, $columns )
    {
        $bindings = array();
        $db = self::db( $conn );

        // Build the SQL query string from the request
        
        $limit = self::limit( $request, $columns );
        $order = self::order( $request, $columns );
        $where = self::filter( $request, $columns, $bindings );

        // Main query to actually get the data
        $data = self::sql_exec( $db, $bindings,
            "SELECT `".implode("`, `", self::pluck($columns, 'db'))."`
             FROM `$table`
             $where
             $order
             $limit"
        );

        // Data set length after filtering
        $resFilterLength = self::sql_exec( $db, $bindings,
            "SELECT COUNT(`{$primaryKey}`)
             FROM   `$table`
             $where"
        );
        $recordsFiltered = $resFilterLength[0][0];

        // Total data set length
        $resTotalLength = self::sql_exec( $db,
            "SELECT COUNT(`{$primaryKey}`)
             FROM   `$table`"
        );
        $recordsTotal = $resTotalLength[0][0];

        /*
         * Output
         */
        return array(
            "draw"            => isset ( $request['draw'] ) ?
                intval( $request['draw'] ) :
                0,
            "recordsTotal"    => intval( $recordsTotal ),
            "recordsFiltered" => intval( $recordsFiltered ),
            "data"            => self::data_output( $columns, $data )
        );
    }


    /**
     * The difference between this method and the `simple` one, is that you can
     * apply additional `where` conditions to the SQL queries. These can be in
     * one of two forms:
     *
     * * 'Result condition' - This is applied to the result set, but not the
     *   overall paging information query - i.e. it will not effect the number
     *   of records that a user sees they can have access to. This should be
     *   used when you want apply a filtering condition that the user has sent.
     * * 'All condition' - This is applied to all queries that are made and
     *   reduces the number of records that the user can access. This should be
     *   used in conditions where you don't want the user to ever have access to
     *   particular records (for example, restricting by a login id).
     *
     *  @param  array $request Data sent to server by DataTables
     *  @param  array|PDO $conn PDO connection resource or connection parameters array
     *  @param  string $table SQL table to query
     *  @param  string $primaryKey Primary key of the table
     *  @param  array $columns Column information array
     *  @param  string $whereResult WHERE condition to apply to the result set
     *  @param  string $whereAll WHERE condition to apply to all queries
     *  @return array          Server-side processing response array
     */
    static function complex ( $request, $conn, $table, $primaryKey, $columns, $whereResult=null, $whereAll=null )
    {
        $bindings = array();
        $db = self::db( $conn );
        $localWhereResult = array();
        $localWhereAll = array();
        $whereAllSql = '';

        // Build the SQL query string from the request
        $limit = self::limit( $request, $columns );
        $order = self::order( $request, $columns );
        $where = self::filter( $request, $columns, $bindings );

        $whereResult = self::_flatten( $whereResult );
        $whereAll = self::_flatten( $whereAll );

        if ( $whereResult ) {
            $where = $where ?
                $where .' AND '.$whereResult :
                'WHERE '.$whereResult;
        }

        if ( $whereAll ) {
            $where = $where ?
                $where .' AND '.$whereAll :
                'WHERE '.$whereAll;

            $whereAllSql = 'WHERE '.$whereAll;
        }

        // Main query to actually get the data
        $data = self::sql_exec( $db, $bindings,
            "SELECT `".implode("`, `", self::pluck($columns, 'db'))."`
             FROM `$table`
             $where
             $order
             $limit"
        );

        // Data set length after filtering
        $resFilterLength = self::sql_exec( $db, $bindings,
            "SELECT COUNT(`{$primaryKey}`)
             FROM   `$table`
             $where"
        );
        $recordsFiltered = $resFilterLength[0][0];

        // Total data set length
        $resTotalLength = self::sql_exec( $db, $bindings,
            "SELECT COUNT(`{$primaryKey}`)
             FROM   `$table` ".
            $whereAllSql
        );
        $recordsTotal = $resTotalLength[0][0];

        /*
         * Output
         */
        return array(
            "draw"            => isset ( $request['draw'] ) ?
                intval( $request['draw'] ) :
                0,
            "recordsTotal"    => intval( $recordsTotal ),
            "recordsFiltered" => intval( $recordsFiltered ),
            "data"            => self::data_output( $columns, $data )
        );
    }


    /**
     * Connect to the database
     *
     * @param  array $sql_details SQL server connection details array, with the
     *   properties:
     *     * host - host name
     *     * db   - database name
     *     * user - user name
     *     * pass - user password
     * @return resource Database connection handle
     */
    static function sql_connect ( $sql_details )
    {
        try {
            $db = @new PDO(
                "mysql:host={$sql_details['host']};dbname={$sql_details['db']}",
                $sql_details['user'],
                $sql_details['pass'],
                array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION )
            );
        }
        catch (PDOException $e) {
            self::fatal(
                "An error occurred while connecting to the database. ".
                "The error reported by the server was: ".$e->getMessage()
            );
        }

        return $db;
    }


    /**
     * Execute an SQL query on the database
     *
     * @param  resource $db  Database handler
     * @param  array    $bindings Array of PDO binding values from bind() to be
     *   used for safely escaping strings. Note that this can be given as the
     *   SQL query string if no bindings are required.
     * @param  string   $sql SQL query to execute.
     * @return array         Result from the query (all rows)
     */
    static function sql_exec ( $db, $bindings, $sql=null )
    {
        // Argument shifting
        if ( $sql === null ) {
            $sql = $bindings;
        }

        $stmt = $db->prepare( $sql );
        //echo $sql;

        // Bind parameters
        if ( is_array( $bindings ) ) {
            for ( $i=0, $ien=count($bindings) ; $i<$ien ; $i++ ) {
                $binding = $bindings[$i];
                $stmt->bindValue( $binding['key'], $binding['val'], $binding['type'] );
            }
        }

        // Execute
        try {
            $stmt->execute();
        }
        catch (PDOException $e) {
            self::fatal( "An SQL error occurred: ".$e->getMessage() );
        }

        // Return all
        return $stmt->fetchAll( PDO::FETCH_BOTH );
    }


    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Internal methods
     */

    /**
     * Throw a fatal error.
     *
     * This writes out an error message in a JSON string which DataTables will
     * see and show to the user in the browser.
     *
     * @param  string $msg Message to send to the client
     */
    static function fatal ( $msg )
    {
        echo json_encode( array( 
            "error" => $msg
        ) );

        exit(0);
    }

    /**
     * Create a PDO binding key which can be used for escaping variables safely
     * when executing a query with sql_exec()
     *
     * @param  array &$a    Array of bindings
     * @param  *      $val  Value to bind
     * @param  int    $type PDO field type
     * @return string       Bound key to be used in the SQL where this parameter
     *   would be used.
     */
    static function bind ( &$a, $val, $type )
    {
        $key = ':binding_'.count( $a );

        $a[] = array(
            'key' => $key,
            'val' => $val,
            'type' => $type
        );

        return $key;
    }


    /**
     * Pull a particular property from each assoc. array in a numeric array, 
     * returning and array of the property values from each item.
     *
     *  @param  array  $a    Array to get data from
     *  @param  string $prop Property to read
     *  @return array        Array of property values
     */
    static function pluck ( $a, $prop )
    {
        $out = array();

        for ( $i=0, $len=count($a) ; $i<$len ; $i++ ) {
            if(empty($a[$i][$prop])){
                continue;
            }
            //removing the $out array index confuses the filter method in doing proper binding,
            //adding it ensures that the array data are mapped correctly
            $out[$i] = $a[$i][$prop];
        }

        return $out;
    }


    /**
     * Return a string from an array or a string
     *
     * @param  array|string $a Array to join
     * @param  string $join Glue for the concatenation
     * @return string Joined string
     */
    static function _flatten ( $a, $join = ' AND ' )
    {
        if ( ! $a ) {
            return '';
        }
        else if ( $a && is_array($a) ) {
            return implode( $join, $a );
        }
        return $a;
    }
}



 

Step4 : put main code of php server_side.php.

server_side.php:

 <?php 
 
 
/*
 * DataTables example server-side processing script.
 *
 * Please note that this script is intentionally extremely simple to show how
 * server-side processing can be implemented, and probably shouldn't be used as
 * the basis for a large complex system. It is suitable for simple use cases as
 * for learning.
 *
 * See http://datatables.net/usage/server-side for full details on the server-
 * side processing requirements of DataTables.
 *
 * @license MIT - http://datatables.net/license_mit
 */
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Easy set variables
 */
 
// DB table to use
$table = 'datatables_demo';
 
// Table's primary key
$primaryKey = 'id';
 
// Array of database columns which should be read and sent back to DataTables.
// The `db` parameter represents the column name in the database, while the `dt`
// parameter represents the DataTables column identifier. In this case simple
// indexes
$columns = array(
    array( 'db' => 'firstname', 'dt' => 0 ),
    array( 'db' => 'lastname',  'dt' => 1 ),
 
    array(
        'db'        => 'email',
        'dt'        => 2,
       
    ),
    /** if   use date  format */
    // array(
    //     'db'        => 'date',
    //     'dt'        => 3,
    //     'formatter' => function( $d, $row ) {
    //         return '$'.number_format($d);
    //     }
    // )
);
 
// SQL server connection information
$sql_details = array(
    'user' => 'root',
    'pass' => '',
    'db'   => 'serverside',
    'host' => 'localhost'
);
 
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * If you just want to use the basic configuration for DataTables with PHP
 * server-side, there is no need to edit below this line.
 */
 
require( 'ssp.class.php' );
 
echo json_encode(
    SSP::simple( $_GET, $sql_details, $table, $primaryKey, $columns )
);
?>