Facebook like photo gallery with comments

Facebook like photo gallery with comments

113 421820
Facebook like photo gallery with comments
Facebook like photo gallery with comments

Facebook like photo gallery with comments

Have you thought about own facebook-style photo gallry system with comments? I think – yes. Today I made up my mind to prepare it for you. Main idea – when we click at images – they popup (ajax) with bigger image at the left and comments section at the right. All images are in the database (mySQL). And, of course, we will use PHP to achieve our result. Also, our comment system will prevent accepting more than 1 comment per 10 mins (to avoid spam).

Live Demo


download in package


Now – download the source files and lets start coding !

Step 1. SQL

For our gallery I prepared two SQL tables: first table keeps records of our images. It contains several fields: title, filename, description, time of adding and comments count. Another table keeps comments. So, execute next SQL instructions:

  `id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) default '',
  `filename` varchar(255) default '',
  `description` text NOT NULL,
  `when` int(11) NOT NULL default '0',
  `comments_count` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`)
INSERT INTO `s281_photos` (`title`, `filename`, `description`, `when`) VALUES
('Item #1', 'photo1.jpg', 'Description of Item #1', UNIX_TIMESTAMP()),
('Item #2', 'photo2.jpg', 'Description of Item #2', UNIX_TIMESTAMP()+1),
('Item #3', 'photo3.jpg', 'Description of Item #3', UNIX_TIMESTAMP()+2),
('Item #4', 'photo4.jpg', 'Description of Item #4', UNIX_TIMESTAMP()+3),
('Item #5', 'photo5.jpg', 'Description of Item #5', UNIX_TIMESTAMP()+4),
('Item #6', 'photo6.jpg', 'Description of Item #6', UNIX_TIMESTAMP()+5),
('Item #7', 'photo7.jpg', 'Description of Item #7', UNIX_TIMESTAMP()+6),
('Item #8', 'photo8.jpg', 'Description of Item #8', UNIX_TIMESTAMP()+7),
('Item #9', 'photo9.jpg', 'Description of Item #9', UNIX_TIMESTAMP()+8),
('Item #10', 'photo10.jpg', 'Description of Item #10', UNIX_TIMESTAMP()+9);
CREATE TABLE IF NOT EXISTS `s281_items_cmts` (
  `c_id` int(11) NOT NULL AUTO_INCREMENT ,
  `c_item_id` int(12) NOT NULL default '0',
  `c_ip` varchar(20) default NULL,
  `c_name` varchar(64) default '',
  `c_text` text NOT NULL ,
  `c_when` int(11) NOT NULL default '0',
  PRIMARY KEY (`c_id`),
  KEY `c_item_id` (`c_item_id`)

Step 2. PHP

Now, please create empty index.php file and put next code:


// disable warnings
if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
  error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php'); // include service classes to work with database and comments
if ($_POST['action'] == 'accept_comment') {
    echo $GLOBALS['MyComments']->acceptComment();
// prepare a list with photos
$sPhotos = '';
$aItems = $GLOBALS['MySQL']->getAll("SELECT * FROM `s281_photos` ORDER by `when` ASC"); // get photos info
foreach ($aItems as $i => $aItemInfo) {
    $sPhotos .= '<div class="photo"><img src="images/thumb_'.$aItemInfo['filename'].'" id="'.$aItemInfo['id'].'" /><p>'.$aItemInfo['title'].' item</p><i>'.$aItemInfo['description'].'</i></div>';
<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="utf-8" />
    <title>Facebook like photo gallery with comments | Script Tutorials</title>
    <!-- Link styles -->
    <link href="css/main.css" rel="stylesheet" type="text/css" />
    <!-- Link scripts -->
    <script src="https://www.google.com/jsapi"></script>
        google.load("jquery", "1.7.1");
    <script src="js/script.js"></script>
        <h2>Facebook like photo gallery with comments</h2>
        <a href="https://www.script-tutorials.com/facebook-like-photo-gallery-with-comments/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
    <!-- Container with last photos -->
    <div class="container">
        <h1>Last photos:</h1>
        <?= $sPhotos ?>
    <!-- Hidden preview block -->
    <div id="photo_preview" style="display:none">
        <div class="photo_wrp">
            <img class="close" src="images/close.gif" />
            <div style="clear:both"></div>
            <div class="pleft">test1</div>
            <div class="pright">test2</div>
            <div style="clear:both"></div>

We have just created main index file of our gallery. By default – script generates a list of images (with title and description), and it also generates an empty hidden object which we are going to use in order to accept custom content by ajax requests. Also, when we post comments, we forward this request (to accept new comment) into comments class. Now, lets review next important php file:


// disable warnings
if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
  error_reporting(E_ALL & ~E_NOTICE);
if ($_POST['action'] == 'get_info' && (int)$_POST['id'] > 0) {
    require_once('classes/CMySQL.php'); // include service classes to work with database and comments
    // get photo info
    $iPid = (int)$_POST['id'];
    $aImageInfo = $GLOBALS['MySQL']->getRow("SELECT * FROM `s281_photos` WHERE `id` = '{$iPid}'");
    // prepare last 10 comments
    $sCommentsBlock = $GLOBALS['MyComments']->getComments($iPid);
    $aItems = $GLOBALS['MySQL']->getAll("SELECT * FROM `s281_photos` ORDER by `when` ASC"); // get photos info
    // Prev & Next navigation
    $sNext = $sPrev = '';
    $iPrev = (int)$GLOBALS['MySQL']->getOne("SELECT `id` FROM `s281_photos` WHERE `id` < '{$iPid}' ORDER BY `id` DESC LIMIT 1");
    $iNext = (int)$GLOBALS['MySQL']->getOne("SELECT `id` FROM `s281_photos` WHERE `id` > '{$iPid}' ORDER BY `id` ASC LIMIT 1");
    $sPrevBtn = ($iPrev) ? '<div class="preview_prev" onclick="getPhotoPreviewAjx(\''.$iPrev.'\')"><img src="images/prev.png" alt="prev" /></div>' : '';
    $sNextBtn = ($iNext) ? '<div class="preview_next" onclick="getPhotoPreviewAjx(\''.$iNext.'\')"><img src="images/next.png" alt="next" /></div>' : '';
    $oJson = new Services_JSON();
    echo $oJson->encode(array(
        'data1' => '<img class="fileUnitSpacer" src="images/'. $aImageInfo['filename'] .'">' . $sPrevBtn . $sNextBtn,
        'data2' => $sCommentsBlock,

This file sends back information about requested photo. This is an enlarged image, block with comments and navigation buttons (to open previous / next images ajaxy). As you can see – we use comments class, now, it’s time to look at it too:


class CMyComments {
    // constructor
    function CMyComments() {
    // return comments block
    function getComments($i) {
        // draw last 10 comments
        $sComments = '';
        $aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `s281_items_cmts` WHERE `c_item_id` = '{$i}' ORDER BY `c_when` DESC LIMIT 10");
        foreach ($aComments as $i => $aCmtsInfo) {
            $sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
            $sComments .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
    <p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
        return <<<EOF
<div class="comments" id="comments">
    <div id="comments_warning1" style="display:none">Don`t forget to fill both fields (Name and Comment)</div>
    <div id="comments_warning2" style="display:none">You can't post more than one comment per 10 minutes (spam protection)</div>
    <form onsubmit="return false;">
            <tr><td class="label"><label>Your name: </label></td><td class="field"><input type="text" value="" title="Please enter your name" id="name" /></td></tr>
            <tr><td class="label"><label>Comment: </label></td><td class="field"><textarea name="text" id="text"></textarea></td></tr>
            <tr><td class="label">&nbsp;</td><td class="field"><button onclick="submitComment({$i}); return false;">Post comment</button></td></tr>
    <div id="comments_list">{$sComments}</div>
    function acceptComment() {
        $iItemId = (int)$_POST['id']; // prepare necessary information
        $sIp = $this->getVisitorIP();
        $sName = $GLOBALS['MySQL']->escape(strip_tags($_POST['name']));
        $sText = $GLOBALS['MySQL']->escape(strip_tags($_POST['text']));
        if ($sName && $sText) {
            // check - if there is any recent post from you or not
            $iOldId = $GLOBALS['MySQL']->getOne("SELECT `c_item_id` FROM `s281_items_cmts` WHERE `c_item_id` = '{$iItemId}' AND `c_ip` = '{$sIp}' AND `c_when` >= UNIX_TIMESTAMP() - 600 LIMIT 1");
            if (! $iOldId) {
                // if everything is fine - allow to add comment
                $GLOBALS['MySQL']->res("INSERT INTO `s281_items_cmts` SET `c_item_id` = '{$iItemId}', `c_ip` = '{$sIp}', `c_when` = UNIX_TIMESTAMP(), `c_name` = '{$sName}', `c_text` = '{$sText}'");
                $GLOBALS['MySQL']->res("UPDATE `s281_photos` SET `comments_count` = `comments_count` + 1 WHERE `id` = '{$iItemId}'");
                // and print out last 10 comments
                $sOut = '';
                $aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `s281_items_cmts` WHERE `c_item_id` = '{$iItemId}' ORDER BY `c_when` DESC LIMIT 10");
                foreach ($aComments as $i => $aCmtsInfo) {
                    $sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
                    $sOut .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
    <p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
                return $sOut;
        return 1;
    // get visitor IP
    function getVisitorIP() {
        $ip = "";
        if( ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) && ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif( ( isset( $_SERVER['HTTP_CLIENT_IP'])) && (!empty($_SERVER['HTTP_CLIENT_IP'] ) ) ) {
            $ip = explode(".",$_SERVER['HTTP_CLIENT_IP']);
            $ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0];
        } elseif((!isset( $_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) {
            if ((!isset( $_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) {
                $ip = $_SERVER['REMOTE_ADDR'];
        return $ip;
$GLOBALS['MyComments'] = new CMyComments();

This class performs two main functions – it can accept new comments and also it can give us a box with comments. There are two more service classes: CMySQL.php and Services_JSON.php. They are two known classes to work with database and json. You can adjust database settings in database class. Both classes available in our package.

Step 3. Javascript

Now we should prepare user interface behavior with using javascript, please prepare next file for the project:


// close photo preview block
function closePhotoPreview() {
    $('#photo_preview .pleft').html('empty');
    $('#photo_preview .pright').html('empty');
// display photo preview block
function getPhotoPreviewAjx(id) {
    $.post('photos_ajx.php', {action: 'get_info', id: id},
            $('#photo_preview .pleft').html(data.data1);
            $('#photo_preview .pright').html(data.data2);
        }, "json"
// submit comment
function submitComment(id) {
    var sName = $('#name').val();
    var sText = $('#text').val();
    if (sName && sText) {
        $.post('index.php', { action: 'accept_comment', name: sName, text: sText, id: id },
                if (data != '1') {
                    $('#comments_list').fadeOut(1000, function () {
                } else {
                    $('#comments_warning2').fadeIn(1000, function () {
    } else {
        $('#comments_warning1').fadeIn(1000, function () {
// init
    // onclick event handlers
    $('#photo_preview .photo_wrp').click(function (event) {
        return false;
    $('#photo_preview').click(function (event) {
    $('#photo_preview img.close').click(function (event) {
    // display photo preview ajaxy
    $('.container .photo img').click(function (event) {
        if (event.preventDefault) event.preventDefault();

Please note, we use jQuery instructions in our script (I hope that you haven’t forgot that we linked jQuery library in the header section through google service).

Step 4. CSS

In the long run, we should stylize our page elements (our container with photos, photo preview area with comments):


/* project styles */
.container {
    border: 1px solid #111111;
    color: #000000;
    margin: 20px auto;
    overflow: hidden;
    padding: 15px;
    position: relative;
    text-align: center;
    width: 1090px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
.photo {
    border: 1px solid transparent;
    float: left;
    margin: 4px;
    overflow: hidden;
    padding: 4px;
    white-space: nowrap;
    /* CSS3 Box sizing property */
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    /* CSS3 transition */
    -moz-transition: border 0.2s ease 0s;
    -ms-transition: border 0.2s ease 0s;
    -o-transition: border 0.2s ease 0s;
    -webkit-transition: border 0.2s ease 0s;
    transition: border 0.2s ease 0s;
.photo:hover {
    border-color: #444;
.photo img {
    cursor: pointer;
    width: 200px;
.photo p, .photo i {
    display: block;
.photo p {
    font-weight: bold;
/* preview styles */
#photo_preview {
    background-color: rgba(0, 0, 0, 0.7);
    bottom: 0;
    color: #000000;
    display: none;
    left: 0;
    overflow: hidden;
    position: fixed;
    right: 0;
    top: 0;
    z-index: 10;
.photo_wrp {
    background-color: #FAFAFA;
    height: auto;
    margin: 100px auto 0;
    overflow: hidden;
    padding: 15px;
    text-align: center;
    vertical-align: middle;
    width: 1000px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
.close {
    cursor: pointer;
    float: right;
.pleft {
    float: left;
    overflow: hidden;
    position: relative;
    width: 600px;
.pright {
    float: right;
    position: relative;
    width: 360px;
.preview_prev, .preview_next {
    cursor: pointer;
    margin-top: -64px;
    opacity: 0.5;
    position: absolute;
    top: 50%;
    -moz-transition: opacity 0.2s ease 0s;
    -ms-transition: opacity 0.2s ease 0s;
    -o-transition: opacity 0.2s ease 0s;
    -webkit-transition: opacity 0.2s ease 0s;
    transition: opacity 0.2s ease 0s;
.preview_prev:hover, .preview_next:hover {
    opacity: 1;
.preview_prev {
    left: 20px;
.preview_next {
    right: 40px;
/* comments styles */
#comments form {
    margin: 10px 0;
    text-align: left;
#comments table td.label {
    color: #000;
    font-size: 13px;
    padding-right: 3px;
    text-align: right;
    width: 105px;
#comments table label {
    color: #000;
    font-size: 16px;
    font-weight: normal;
    vertical-align: middle;
#comments table td.field input, #comments table td.field textarea {
    border: 1px solid #96A6C5;
    font-family: Verdana,Arial,sans-serif;
    font-size: 16px;
    margin-top: 2px;
    padding: 6px;
    width: 250px;
#comments_list {
    margin: 10px 0;
    text-align: left;
#comments_list .comment {
    border-top: 1px solid #000;
    padding: 10px 0;
#comments_list .comment:first-child {
#comments_list .comment span {
    font-size: 11px;

Live Demo


And again, we have just prepared our next practically useful tutorial. Sure that this material will useful for your own projects. Good luck in your work!


Understanding Closures

0 24585


  1. Hello ,
    the gallery is very nice and i made it work but can you tell me if i can insert for each picture a like button+count box, just like facebook plugin?

    Your answer it will be very helpfull since i haven;t much experience in php

    Thank you.

    • Hi Remus,
      Yes, this is possible, and you can implement the ‘like’ functionality in the similar way as comments were implemented. It means – you can expand the table with photos (one new field), and after – ajaxy ‘liking’ functionality

    • Hi Josh,
      This is pretty easy:
      #comments_list {
      margin: 10px 0;
      max-height: 500px;
      overflow-y: scroll;
      text-align: left;

  2. am new here….i was trying import the “s281” database but am having errors…

    is there any special way to installllll???

    • yes…i’ve figured the database issue….do this plugin have an upload section???it will be nice if it does..

      • Hi Fehintoluwa,
        No, we did not make the upload, because it is always discussed and explained a lot (in our other articles). Just search for it.

  3. Hi Fehintoluwa,
    No, there is no any special way. You can simply goto your phpMyAdmin, then to ‘SQL’ (or import) – and after – import it.

  4. Hello Sir,

    You Really solved my problem, I was looking for something like this. But Sir I want to make this in ASP.NET so could you please help me out!!!!! Or could you please tell me from where I can get the code for .NET Application!!!!!!

    • Hello Anubhav,
      It doesn’t matter what language you use, you can even use C++ if you need.
      In any case, the result is pure HTML code. You just need to find a way how to display HTML code in ASP.NET.

  5. Hello,
    – what’s the use/functionality of the file “Services_JSON”?
    – why does this application need it?
    – what will happen without it?

    • Hi Jean,
      This is PHP class to use ‘json’ commands (decode-encode). But you can substitute it with ‘json_decode’ and ‘json_encode’.

  6. Hi again Admin!
    I have a small problem:when i put a links somewhere on the popped up “div”(i mean:class=”photo_wrp”) ,there is no effect when i click those links,how can i make links or anything clickable i want to add anywhere on that popped up “div” box to be clickable?thanks![tip: there might be something preventing my links from being clicked in the”script.js”file ]

    • Hi Jean,
      Yes, there is the preventing code, search for the ‘onclick event handlers’ comment in the ‘script.js’ file.

  7. Hello Admin…
    I appreciate for the script you post, But I got one issue…I am running it to the localhost but just to check i am uploading it to my domain…here is the link
    when i am clicking the image, i am not getting any pop-up. I have extracted your package and didn’t touch anything except DB modification part…I tried a lot to figure out but no solution…please solve my problem as i am running out of deadline.


    • Hi Rahul,
      I think that you have some mistakes in PHP, did you configure your DB params in classes/CMySQL.php file?

  8. Hello,

    Long time I was looking for a script like this. Finally I have found it but can not use because I don’t know the javascript but this script needs to be modified so that I can use it for my purposes.

    Some suggestions to improve the script.

    1. When you click on a thumbnail, image box must appear immediately and can show something like “Loading….” In this script version image box appears only when the photo is 100% loaded. This website loads very slow for me and sometimes I wait 3-5 seconds until image box appears.

    2. “previous” and “next” buttons should appear only on mouseover. It’s not nice to see huge “previous” and “next” button on each photo even they are lighter than on mouseover.

    3. A possibility to show a bigger version (original) of a photo is needed.

    4. I don’t understand why I can not scroll the page to see the bottom of a photo box… It looks like a bug.

    5. “Like” button (icon) would be very nice to see on mouse over.

    6. Slideshow would be very nice.

    I am willing to pay for a script if I have all these features but this version is not very rich of features.

    • Hi lpss,
      Thank you for all your valuable notes about the script. Indeed, there was no need to introduce all possible features in this script, as it is not a commercial product, it’s just a demonstration how these galleries work in practice. You may contact me directly about your custom offer.

  9. hello sir,
    when i implement this, neither images nor the comment box gets displayed on web page. it dono’t show any error but i am stuck with images and commenting part. but when i write the src for all the images in line no: 48 in index.php after removing then it works fine and if i write only and remove the src, its not working. but i want that images should be fetched but its not working. i need this one badly. help me

    • Hi Olly,
      I think that you forgot to set your database settings in the ‘classes/CMySQL.php’ file (in the beginning)

  10. hi. i want to ask. im done executing sql queries, changing mysql connection and when i try to load the index file i cant see the photos and the info of it. :( what should i do?

  11. Hi Sir,
    This looks great! But I need to bring all the media files(photos, videos, PDF, audio ….) in the page into the gallery.

    Can I have an sample code for this or any idea how can I put them in?

    Please help.
    Thx :)

    • Hello Saravana,
      Yes, you may combine it all into a single gallery, which could be done in the similar way as this tutorial, you also can apply ‘pinterest’-like styles (it seems that it is popular today)

  12. I have problem with comments storing at back end.when i enter comments first time it works fine bt later its storing c_item_id as 0 in table when i add comments.. please help.

    • Hi Messias,
      I recommend that you debug the following function: acceptComment.
      You should pay attention what you have for $iItemId = (int)$_POST[‘id’]

  13. hi i really liked your code ,i did the mysql connection but it doesn’t pop up on clicking

    • Hi Sharmila,
      Did you get any SQL error when you click? I can suggest that you re-check your mysql connection details (CMySQL.php)

    • In the constructor of the class you can find:
      $this->sDbName = ‘YOUR_DB_NAME’;
      $this->sDbUser = ‘DB_USER_NAME’;
      $this->sDbPass = ‘DB_USER_PASS’;
      So, the first param is database name, the second is database username, and the third param is database user password.

  14. Mind a small typo:
    Have you thought about own facebook-style photo gallry – gallEry ;-)

    Great tutorilas Andrew, thanks!!


    • Hi Mayki,
      Thank you for your comment here. Yes, I thought, however I decided to develop another photo gallery: pinterest gallery :-)

  15. hey there,
    very nice script an useful for me,thx a lot
    i have 1 question
    how to put comment list top and comment form bottom.

    thx for help

    • Hi Evident,
      In order to move the posting form, you just need to make changes in HTML, you need to move the Form into the .pleft element

  16. Great script, thanks for the tutorial. I’ve used your script as an includes file but somehow the comments are now being prevented from being accepted, I’m getting a redirect to my landing page.. I changed the script’s file name to gallery.php…. Is there a file where you define where the comments must be displayed after submitting? Hope it makes sense…. Thanks again

  17. Is a problem with this script
    when i post a coment first time is ok but when i try to leave another comment is not working
    in database will put c_item_id = 0
    just try to download source code and try, this
    post a comment after refresh page and after try to put another comment

  18. Hi sir i am using u r facebook image gallery code it’s working fine but i have some problem in that i want comments scrolling and any size image display in middle of the lightbox plz tell me any solution

  19. Hello, I used this tutorial as a base for my gallery on this url: http://invictotv.com/galeria-1 and works great, the downside is showing no written comments unless you write a new one, check the original files and gives the same drawback, but seeing the demo I see you have here works perfectly, what can be the problem?

    • Hi Luis,
      It is difficult to say certainly. It could be in case of wrong database credentials – try to check it.

    • Hi Tes,
      In case if you want to use facebook comments, then nearly a half of our tutorial will be useless for you. In your case – you just need to get code for fb comments (from facebook) and put it instead of our comments.

  20. Hi,

    How i can simple HTML file, because i don’t know PHP and SQL, Is there any way i can make simple HTML file. Please help me.


    • Hello Dalbir,
      Unfortunately, you can not use database (mysql) from only html. It should be coded in PHP (or any other server language)

    • Hi Abhinandan,
      As I remember, there are functions to print a string (in ASP / C#), so – just use it to print html code. As for php – you will need to redevelop it completely to use it in ASP

Leave a Reply