PHP Code – How to create a Live Demo for free on 000webhost.com (outdated)
People often ask me, how i created the live demo at https://phpfm-demo.000webhostapp.com.
It resets automatically every hour, and shows a timer for the next reset.
Here i share the code, so if you have a project on GitHub and want to create a live demo, you can use it as base.
000webhostapp.com is a free webhosting service, and all you have to do is leave their banner on your demo.
demo-reset.php
This is the main script, it runs on my server crontab every hour.
<?php // Run on CRON every hour // 0 * * * * www-data wget -q --spider http://[URL TO DEMO-RESET] >/dev/null 2>&1 // FTP functions function ftp_list($conn, $remote_path='.', &$output) { $entry_list = ftp_rawlist($conn, $remote_path); if (is_array($entry_list)) { $items = array(); foreach ($entry_list as $entry) { $chunks = preg_split("/\s+/", $entry); list($item['rights'], $item['number'], $item['user'], $item['group'], $item['size'], $item['month'], $item['day'], $item['time']) = $chunks; $item['type'] = $chunks[0]{0} === 'd' ? 'directory' : 'file'; array_splice($chunks, 0, 8); // Remove 8 itens separated by space $item['name'] = implode(" ", $chunks); // concat the rest, that is the name of the file if ($item['name'] == '.' || $item['name'] == '..') continue; $items[] = $item; } return $items; } else { $output .= "ftp_rawlist() error: ".$remote_path."<br>\n"; } return false; } function ftp_total_delete($conn, $remote_path, &$output){ $item_list = ftp_list($conn, $remote_path, $output); $ok = ($item_list !== false); if ($ok) { foreach ($item_list as $item) { $curr_remote_path = $remote_path; if ($curr_remote_path == '/') $curr_remote_path = ''; $curr_remote_path = $curr_remote_path.'/'.$item['name']; if ($ok) { if ($item['type'] == 'file') { $ok = ftp_delete($conn, $curr_remote_path); $output .= "FTP RM: ".$curr_remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; } elseif ($item['type'] == 'directory') { $ok = ftp_total_delete($conn, $curr_remote_path, $output); if ($ok) { $ok = ftp_rmdir($conn, $curr_remote_path); $output .= "FTP RMDIR: ".$curr_remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; } } } } } return $ok; } function ftp_total_upload($conn, $local_path, $remote_path, &$output){ $ok = true; $entry_list = scandir($local_path); foreach ($entry_list as $entry_name) { if ($entry_name == '.' || $entry_name == '..') continue; if ($ok) { $curr_local_path = $local_path.'/'.$entry_name; $curr_remote_path = $remote_path; if ($curr_remote_path == '/') $curr_remote_path = ''; $curr_remote_path = $curr_remote_path.'/'.$entry_name; if (is_dir($curr_local_path)) { $ok = ftp_mkdir($conn, $curr_remote_path); $output .= "FTP MKDIR: ".$curr_remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) { $ok = ftp_total_upload($conn, $curr_local_path, $curr_remote_path, $output); } } elseif (is_file($curr_local_path)) { $ok = ftp_put($conn, $curr_remote_path, $curr_local_path, FTP_BINARY); $output .= "FTP UPLOAD: ".$curr_local_path." => ".$curr_remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; } } } return $ok; } function ftp_total_download($conn, $remote_path, $local_path, &$output){ $max_file_size = 15 * 1024 * 1024; // Mb em bytes $item_list = ftp_list($conn, $remote_path, $output); $ok = ($item_list !== false); if ($ok) { foreach ($item_list as $item) { $curr_local_path = $local_path.'/'.$item['name']; if (strpos($curr_local_path,'.php') !== false) $curr_local_path .= '.txt'; $curr_remote_path = $remote_path; if ($curr_remote_path == '/') $curr_remote_path = ''; $curr_remote_path = $curr_remote_path.'/'.$item['name']; if ($ok) { if ($item['type'] == 'file') { if ($item['size'] < $max_file_size){ $ok = ftp_get($conn, $curr_local_path, $curr_remote_path, FTP_BINARY); $output .= "FTP GET: ".$curr_remote_path." => ".$curr_local_path." = ".($ok?'OK':'ERRO')."<br>\n"; } else { $output .= "FTP GET IGNORED: ".$curr_remote_path." => ".$curr_local_path." = (".formatsize($item['size']).")<br>\n"; } } elseif ($item['type'] == 'directory') { if ($ok) { if (!is_dir($curr_local_path)){ $ok = mkdir($curr_local_path); $output .= "MKDIR: ".$curr_local_path." = ".($ok?'OK':'ERRO')."<br>\n"; } } $ok = ftp_total_download($conn, $curr_remote_path, $curr_local_path, $output); } } } } return $ok; } // Format functions function formatsize($arg) { if ($arg>0){ $j = 0; $ext = array(" bytes"," Kb"," Mb"," Gb"," Tb"); while ($arg >= pow(1024,$j)) ++$j; { $arg = (round($arg/pow(1024,$j-1)*100)/100).($ext[$j-1]); } return $arg; } else return "0 Kb"; } // Main Script function demo_reset(){ $ftp_host = 'files.000webhost.com'; $ftp_user = '[USER]'; $ftp_pass = '[PASSWORD]'; $ftp_root = '/storage/ssd4/595/8669595/public_html'; $conn = ftp_connect($ftp_host,21,10); $ok = ($conn !== false); echo "FTP CONNECT: ".$ftp_host." = ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) { ftp_set_option($conn, FTP_TIMEOUT_SEC, 10); $ok = ftp_login($conn, $ftp_user, $ftp_pass); echo "FTP LOGIN: ".($ok?'OK':'ERRO')."<br>\n"; } if ($ok) { echo "<br>\n"; $ftp_root = '/'; $output = ''; $ok = ftp_total_delete($conn, $ftp_root, $output); echo "FTP TOTAL DELETE: ".$ftp_root." = ".($ok?'OK':'ERRO')."<br>\n"; echo $output; } if ($ok) { echo "<br>\n"; $local_root = './demo-reset/_docroot'; $ftp_root = '/'; $output = ''; $ok = ftp_total_upload($conn, $local_root, $ftp_root, $output); echo "FTP TOTAL UPLOAD: ".$local_root." => ".$ftp_root." = ".($ok?'OK':'ERRO')."<br>\n"; echo $output; } if ($ok) { echo "<br>\n"; $ok = (ftp_chmod($conn, 0755, $ftp_root) !== false); // Returns the new file permissions on success or FALSE on error. echo "FTP CHMOD 0755 ".$ftp_root.": ".($ok?'OK':'ERRO')."<br>\n"; } if ($ok) { echo "<br>\n"; $local_path = './demo-reset/php-get-time.txt'; $remote_name = 'php-get-time-'.time().'.php'; $remote_path = '/public_html/'.$remote_name; $remote_url = 'https://phpfm-demo.000webhostapp.com/'.$remote_name; if (is_file($local_path)) { $ok = ftp_put($conn, $remote_path, $local_path, FTP_BINARY); echo "FTP UPLOAD: ".$local_path." => ".$remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) { $time = file_get_contents($remote_url); $ok = ($time !== false); echo "HTTP GET: ".$remote_url." = ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) { echo "TIME: ".$time."<br>\n"; } $ok = ftp_delete($conn, $remote_path); echo "FTP RM: ".$remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; } } } if ($ok) { echo "<br>\n"; $local_root = './demo-reset/_docroot'; if ($ok) { $remote_url = 'https://raw.githubusercontent.com/dulldusk/phpfm/master/index.php'; $phpfm_src = file_get_contents($remote_url); $ok = ($phpfm_src !== false); echo "HTTP GET: ".$remote_url." = ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) { $local_path = $local_root.'/phpfm.txt'; $remote_path = '/public_html/phpfm.php'; if (file_put_contents($local_path,$phpfm_src)) { echo "SAVED AS: ".$local_path."<br>\n"; $ok = ftp_put($conn, $remote_path, $local_path, FTP_BINARY); echo "FTP UPLOAD: ".$local_path." => ".$remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; unlink($local_path); } } } if ($ok) { $time = intval($time); if (!$time) $time = time(); $index_str = file_get_contents('./demo-reset/index.txt'); $index_str = str_replace('[START-TIME]',$time,$index_str); $local_path = $local_root.'/index.txt'; $remote_path = '/public_html/index.php'; if (file_put_contents($local_path,$index_str)) { $ok = ftp_put($conn, $remote_path, $local_path, FTP_BINARY); echo "FTP UPLOAD: ".$local_path." => ".$remote_path." = ".($ok?'OK':'ERRO')."<br>\n"; unlink($local_path); } } } ftp_close($conn); return $ok; } $GLOBALS['script_init_time'] = getmicrotime(); @set_time_limit(60); $max_tries = 1; for($i=0;$i<$max_tries;$i++){ if ($i>0) { sleep(2); echo "<br>\n"; } $ok = demo_reset(); echo "<br>\n"; echo "<b>DEMO RESET</b>: ".($ok?'OK':'ERRO')."<br>\n"; if ($ok) break; } echo "<br>\n"; echo "page generated in ".number_format((getmicrotime()-$GLOBALS['script_init_time']), 3, '.', '')."s (limit ".ini_get("max_execution_time")."s) using ".formatsize(memory_get_usage())." (limit ".ini_get("memory_limit").")"; ?>
demo-reset.php output:
FTP CONNECT: files.000webhost.com = OK
FTP LOGIN: OK
FTP TOTAL DELETE: / = OK
FTP RM: /public_html/LICENSE = OK
FTP RM: /public_html/README.md = OK
FTP RM: /public_html/index.php = OK
FTP RM: /public_html/phpfm.php = OK
FTP RMDIR: /public_html = OK
FTP TOTAL UPLOAD: ./demo-reset/_docroot => / = OK
FTP MKDIR: /public_html = OK
FTP UPLOAD: ./demo-reset/_docroot/public_html/LICENSE => /public_html/LICENSE = OK
FTP UPLOAD: ./demo-reset/_docroot/public_html/README.md => /public_html/README.md = OK
FTP UPLOAD: ./demo-reset/php-get-time.txt => /public_html/php-get-time-1587236205.php = OK
HTTP GET: https://phpfm-demo.000webhostapp.com/php-get-time-1587236205.php = OK
TIME: 1587236281
FTP RM: /public_html/php-get-time-1587236205.php = OK
HTTP GET: https://raw.githubusercontent.com/dulldusk/phpfm/master/index.php = OK
SAVED AS: ./demo-reset/_docroot/phpfm.txt
FTP UPLOAD: ./demo-reset/_docroot/phpfm.txt => /public_html/phpfm.php = OK
FTP UPLOAD: ./demo-reset/_docroot/index.txt => /public_html/index.php = OK
DEMO RESET: OK
page generated in 2.024s (limit 60s) using 706.48 Kb (limit 50M)
php-get-time.txt
A simple php script to get the current time at the 000webhost server. It is uploaded, and removed afterwards.
<?php echo time(); ?>
index.txt
This is the HTML file, that is updated by demo-reset.php with the 000webhost server current time, and uploaded as index.php, creating the frameset with the counter for the demo.
<?php header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); header("Content-Type: text/html; charset=UTF-8"); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="//www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <link rel="shortcut icon" href="phpfm.php?action=99&filename=favicon.ico" type="image/x-icon"> <title>PHP File Manager - Demo</title> <style type="text/css"> html { width: 100%; margin-left: 0 !important; } body { font-family : Arial; font-size: 18px; font-weight : normal; color: #000000; background-color: #EEEEEE; } a { font-family : Arial; font-size : 18px; text-decoration: none; color: #000000; cursor: pointer; } a:link { color: #000000; } a:visited { color: #000000; } a:hover { color: #0A77F7; } a:active { color: #000000; } #sfdownload { position: absolute; top: 0; left: 0; padding-top: 8px; padding-left: 10px; } #timerInfo { position: absolute; top: 0; left: 290px; padding-top: 12px; padding-left: 10px; font-size: 18px; } #paypalDiv { position: absolute; top: 0; left: 1020px; padding-top: 4px; padding-left: 10px; } #paypalBut { height: 56px; border: none; cursor: pointer; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <?php if (isset($_REQUEST['top'])){ echo ' <body> <div id="sfdownload"> <a target="_blank" href="https://sourceforge.net/projects/phpfm/files/latest/download"><img alt="Download PHP File Manager" src="https://a.fsdn.com/con/app/sf-download-button" width=276 height=48 srcset="https://a.fsdn.com/con/app/sf-download-button?button_size=2x 2x"></a> </div> <div id="timerInfo"> <b><a target="_blank" href="https://github.com/dulldusk/phpfm/archive/master.zip" target="_blank">PHP File Manager Demo - Github Latest</a></b> <br \> Feel free to mess around! This is a public demo installation<span id="time">, and will reset itself every hour.</span> </div> <div id="paypalDiv"> <a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=dulldusk@gmail.com&item_name='.urlencode('Donation for phpFileManager').'&item_number='.urlencode('Help me create new features. Any amount is well received!').'&amount=0%2e00¤cy_code=USD"> <img id="paypalBut" src="//www.dulldusk.com/paypal.png" title="Donate with PayPal"> </a> </div> <script LANGUAGE="JavaScript"> <!-- function startTimer(duration, display) { var start = Date.now(); var diff, minutes, seconds, timerIntervalID; function timer() { diff = duration - (((Date.now() - start) / 1000) | 0); if (diff >= 0) { // does the same job as parseInt truncates the float minutes = (diff / 60) | 0; seconds = (diff % 60) | 0; minutes_str = minutes < 10 ? "0" + minutes : minutes; seconds_str = seconds < 10 ? "0" + seconds : seconds; display.textContent = ", and will reset itself in " + minutes_str + ":" + seconds_str + "."; if (diff <= 0) { start = start + 1000; // add one second so that the count down starts at the full duration } if (minutes == 0 && seconds == 0){ clearInterval(timerIntervalID); setTimeout(function(){ window.top.document.location.href = "https://phpfm-demo.000webhostapp.com"; },1000); } } else { clearInterval(timerIntervalID); //display.textContent = "00:00"; display.textContent = ", and will reset itself every hour."; } $(\'div:has(a:has(img[alt="www.000webhost.com"]))\').remove(); }; timer(); timerIntervalID = setInterval(timer, 1000); } var server_time_on_demo_reset = [START-TIME]; var server_time_now = '.time().'; window.onload = function () { var durationMinutes = 60; var durationSeconds = (durationMinutes * 60) - (server_time_now - server_time_on_demo_reset) + 15; var display = document.querySelector(\'#time\'); startTimer(durationSeconds, display); }; //--> </script> </body> '; } else { echo ' <frameset rows="64,*" framespacing="0" frameborder="1"> <frame src="index.php?top" name=frametop border="0" marginwidth="0" marginheight="0" scrolling="no"> <frame src="phpfm.php" name=framephpfm border="0" marginwidth="0" marginheight="0"> </frameset> '; } ?> </html>
Hope you like it!