Servers can be configured to show the contents of a directory that doesn't have an index file to render. The result is usually less than visually spectacular:
Lackluster default in Chrome
More better, View Demo
We can take control of this ourselves by replicating this functionality with PHP.
Make an index file (.index.php
, starting with the dot, really) which reads the files in the directory and outputs them into a table
Make an .htaccess
file that serves that file as the index
Have the index file load in CSS and other resources that are also prefixed with a dot (hidden)
The following PHP reads the directory of files and displays a styled table of their name, file type, and file size. It also applies a class name in which to apply icons for the different major file types (see CSS).
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Directory Contents</title>
<link rel="stylesheet" href=".style.css">
<script src=".sorttable.js"></script>
</head>
<body>
<div id="container">
<h1>Directory Contents</h1>
<table class="sortable">
<thead>
<tr>
<th>Filename</th>
<th>Type</th>
<th>Size <small>(bytes)</small></th>
<th>Date Modified</th>
</tr>
</thead>
<tbody>
<?php
// Opens directory
$myDirectory=opendir(".");
// Gets each entry
while($entryName=readdir($myDirectory)) {
$dirArray[]=$entryName;
}
// Finds extensions of files
function findexts ($filename) {
$filename=strtolower($filename);
$exts=split("[/\\.]", $filename);
$n=count($exts)-1;
$exts=$exts[$n];
return $exts;
}
// Closes directory
closedir($myDirectory);
// Counts elements in array
$indexCount=count($dirArray);
// Sorts files
sort($dirArray);
// Loops through the array of files
for($index=0; $index < $indexCount; $index++) {
// Allows ./?hidden to show hidden files
if($_SERVER['QUERY_STRING']=="hidden")
{$hide="";
$ahref="./";
$atext="Hide";}
else
{$hide=".";
$ahref="./?hidden";
$atext="Show";}
if(substr("$dirArray[$index]", 0, 1) != $hide) {
// Gets File Names
$name=$dirArray[$index];
$namehref=$dirArray[$index];
// Gets Extensions
$extn=findexts($dirArray[$index]);
// Gets file size
$size=number_format(filesize($dirArray[$index]));
// Gets Date Modified Data
$modtime=date("M j Y g:i A", filemtime($dirArray[$index]));
$timekey=date("YmdHis", filemtime($dirArray[$index]));
// Prettifies File Types, add more to suit your needs.
switch ($extn){
case "png": $extn="PNG Image"; break;
case "jpg": $extn="JPEG Image"; break;
case "svg": $extn="SVG Image"; break;
case "gif": $extn="GIF Image"; break;
case "ico": $extn="Windows Icon"; break;
case "txt": $extn="Text File"; break;
case "log": $extn="Log File"; break;
case "htm": $extn="HTML File"; break;
case "php": $extn="PHP Script"; break;
case "js": $extn="Javascript"; break;
case "css": $extn="Stylesheet"; break;
case "pdf": $extn="PDF Document"; break;
case "zip": $extn="ZIP Archive"; break;
case "bak": $extn="Backup File"; break;
default: $extn=strtoupper($extn)." File"; break;
}
// Separates directories
if(is_dir($dirArray[$index])) {
$extn="<Directory>";
$size="<Directory>";
$class="dir";
} else {
$class="file";
}
// Cleans up . and .. directories
if($name=="."){$name=". (Current Directory)"; $extn="<System Dir>";}
if($name==".."){$name=".. (Parent Directory)"; $extn="<System Dir>";}
// Print 'em
print("
<tr class='$class'>
<td><a href='./$namehref'>$name</a></td>
<td><a href='./$namehref'>$extn</a></td>
<td><a href='./$namehref'>$size</a></td>
<td sorttable_customkey='$timekey'><a href='./$namehref'>$modtime</a></td>
</tr>");
}
}
?>
</tbody>
</table>
<h2><?php print("<a href='$ahref'>$atext hidden files</a>"); ?></h2>
</div>
</body>
</html>
The resources loaded in that index file are the top-in table sorter script sortable.js and a .style.css file. (Remember, prefacing the files with a dot makes the invisible in most operating systems, and also won't show up in your directory of files (good)). Here's that CSS:
* {
padding:0;
margin:0;
}
body {
color: #333;
font: 14px Sans-Serif;
padding: 50px;
background: #eee;
}
h1 {
text-align: center;
padding: 20px 0 12px 0;
margin: 0;
}
h2 {
font-size: 16px;
text-align: center;
padding: 0 0 12px 0;
}
#container {
box-shadow: 0 5px 10px -5px rgba(0,0,0,0.5);
position: relative;
background: white;
}
table {
background-color: #F3F3F3;
border-collapse: collapse;
width: 100%;
margin: 15px 0;
}
th {
background-color: #FE4902;
color: #FFF;
cursor: pointer;
padding: 5px 10px;
}
th small {
font-size: 9px;
}
td, th {
text-align: left;
}
a {
text-decoration: none;
}
td a {
color: #663300;
display: block;
padding: 5px 10px;
}
th a {
padding-left: 0
}
td:first-of-type a {
background: url(./.images/file.png) no-repeat 10px 50%;
padding-left: 35px;
}
th:first-of-type {
padding-left: 35px;
}
td:not(:first-of-type) a {
background-image: none !important;
}
tr:nth-of-type(odd) {
background-color: #E6E6E6;
}
tr:hover td {
background-color:#CACACA;
}
tr:hover td a {
color: #000;
}
/* icons for file types (icons by famfamfam) */
/* images */
table tr td:first-of-type a[href$=".jpg"],
table tr td:first-of-type a[href$=".png"],
table tr td:first-of-type a[href$=".gif"],
table tr td:first-of-type a[href$=".svg"],
table tr td:first-of-type a[href$=".jpeg"]
{background-image: url(./.images/image.png);}
/* zips */
table tr td:first-of-type a[href$=".zip"]
{background-image: url(./.images/zip.png);}
/* css */
table tr td:first-of-type a[href$=".css"]
{background-image: url(./.images/css.png);}
/* docs */
table tr td:first-of-type a[href$=".doc"],
table tr td:first-of-type a[href$=".docx"],
table tr td:first-of-type a[href$=".ppt"],
table tr td:first-of-type a[href$=".pptx"],
table tr td:first-of-type a[href$=".pps"],
table tr td:first-of-type a[href$=".ppsx"],
table tr td:first-of-type a[href$=".xls"],
table tr td:first-of-type a[href$=".xlsx"]
{background-image: url(./.images/office.png)}
/* videos */
table tr td:first-of-type a[href$=".avi"],
table tr td:first-of-type a[href$=".wmv"],
table tr td:first-of-type a[href$=".mp4"],
table tr td:first-of-type a[href$=".mov"],
table tr td:first-of-type a[href$=".m4a"]
{background-image: url(./.images/video.png);}
/* audio */
table tr td:first-of-type a[href$=".mp3"],
table tr td:first-of-type a[href$=".ogg"],
table tr td:first-of-type a[href$=".aac"],
table tr td:first-of-type a[href$=".wma"]
{background-image: url(./.images/audio.png);}
/* web pages */
table tr td:first-of-type a[href$=".html"],
table tr td:first-of-type a[href$=".htm"],
table tr td:first-of-type a[href$=".xml"]
{background-image: url(./.images/xml.png);}
table tr td:first-of-type a[href$=".php"]
{background-image: url(./.images/php.png);}
table tr td:first-of-type a[href$=".js"]
{background-image: url(./.images/script.png);}
/* directories */
table tr.dir td:first-of-type a
{background-image: url(./.images/folder.png);}
View Demo Download Files
REMEMBER: The .zip file might appear to be empty, but it's not. The files are all prefaced with a dot. View them in a file editor which shows you "hidden" files.
Special thanks to Cliff White.
Update November 2012: The demo and downloadable files have been updated to 1) show more human readable file sizes 2) have error pages
<?php
//get cool feedburner count
$whaturl="http://api.feedburner.com/awareness/1.0/GetFeedData?uri=your feedburner id";
//Initialize the Curl session
$ch = curl_init();
//Set curl to return the data instead of printing it to the browser.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//Set the URL
curl_setopt($ch, CURLOPT_URL, $whaturl);
//Execute the fetch
$data = curl_exec($ch);
//Close the connection
curl_close($ch);
$xml = new SimpleXMLElement($data);
$fb = $xml->feed->entry['circulation'];
echo $fb;
//end get cool feedburner count
?>
Replace "your feedburner id" with your actual FeedBurner ID. Also, make sure your "Awareness API" is turned on in your FeedBurner settings for the particular feed you are pulling from.
echo '<pre>';
print_r ($_POST);
echo '</pre>';
<?php
$gravatar_link = 'http://www.gravatar.com/avatar/' . md5($comment_author_email) . '?s=32';
echo '<img src="' . $gravatar_link . '" />';
?>
The variable "$comment_author_email" would be a string of a valid email address. If the email isn't in the Gravatar database, it will return a default graphic. "$comment_author_email" is the default WordPress variable that populates from a cookie for people who have previously commented (if the theme supports it).
This is a completely styled page which displays meta tag information it pulls from provided URLs. Change the URL's at the top of the code to change the websites it gathers the information from.
<?php $searchmeta1 = get_meta_tags("http://northstarmediainc.com"); ?>
<?php $searchmeta2 = get_meta_tags("http://thecouponmagazine.com"); ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Meta Tag Finder</title>
<style>
*{
margin:0;
padding:0;
outline:0;
border:0;
}
html{min-height:100%; height:auto;}
body{
background:#FFF;
font-size:12px;
font-family:verdana, arial, sans-serif;
color:000;
}
a{
text-decoration:none;
color:#999;
}
a:hover{
color:#666;
}
#container{
width:900px;
margin:0 auto;
}
h1{
font-weight:bold;
font-size:20px;
text-align:center;
padding:14px;
letter-spacing:1.5;
font-family: georgia, Sans-Serif;
border-bottom:1px dashed #666;
margin-bottom:20px;
}
h2{
font-weight:normal;
font-size:16px;
padding-top:10px;
}
h3{
font-weight:boldl;
font-size:14px;
text-align:center;
padding-bottom:10px;
font-style:italic;
}
#left{
float:left;
width:430px;
padding-bottom:40px;
}
#right{
float:right;
width:430px;
padding-bottom:40px;
}
.box1{
display:block;
height:70px;
color:#FFF;
background-color:#EF810E;
margin:10px;
padding:10px;
border:1px solid #CF6B00;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
box-shadow: 10px 10px 5px #888;
}
.box2{
display:block;
height:70px;
color:#FFF;
background-color:#5C66FF;
margin:10px;
padding:10px;
border:1px solid #3340CF;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
}
</style>
</head>
<body>
<div id="container">
<h1>Meta Tag Finder</h1>
<div id="left">
<h3>NorthStar Media</h3>
<h2>Author:</h2>
<div class="box1">
<?php echo ($searchmeta1["author"]); ?>
</div>
<h2>Copyright:</h2>
<div class="box1">
<?php echo ($searchmeta1["copyright"]); ?>
</div>
<h2>Description:</h2>
<div class="box1">
<?php echo ($searchmeta1["description"]); ?>
</div>
<h2>Keywords:</h2>
<div class="box1">
<?php echo ($searchmeta1["keywords"]); ?>
</div>
<h2>Robots:</h2>
<div class="box1">
<?php echo ($searchmeta1["robots"]); ?>
</div>
<h2>Generator:</h2>
<div class="box1">
<?php echo ($searchmeta1["generator"]); ?>
</div>
</div>
<div id="right">
<h3>The Coupon Magazine</h3>
<h2>Author:</h2>
<div class="box2">
<?php echo ($searchmeta2["author"]); ?>
</div>
<h2>Copyright:</h2>
<div class="box2">
<?php echo ($searchmeta2["copyright"]); ?>
</div>
<h2>Description:</h2>
<div class="box2">
<?php echo ($searchmeta2["description"]); ?>
</div>
<h2>Keywords:</h2>
<div class="box2">
<?php echo ($searchmeta2["keywords"]); ?>
</div>
<h2>Robots:</h2>
<div class="box2">
<?php echo ($searchmeta2["robots"]); ?>
</div>
<h2>Generator:</h2>
<div class="box2">
<?php echo ($searchmeta2["generator"]); ?>
</div>
</div>
</div>
</body>
</html>
Reference URL
Returns "City, State" if found otherwise the default set at the top.
function detect_city($ip) {
$default = 'UNKNOWN';
if (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost')
$ip = '8.8.8.8';
$curlopt_useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)';
$url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip);
$ch = curl_init();
$curl_opt = array(
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_USERAGENT => $curlopt_useragent,
CURLOPT_URL => $url,
CURLOPT_TIMEOUT => 1,
CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_HOST'],
);
curl_setopt_array($ch, $curl_opt);
$content = curl_exec($ch);
if (!is_null($curl_info)) {
$curl_info = curl_getinfo($ch);
}
curl_close($ch);
if ( preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs) ) {
$city = $regs[1];
}
if ( preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs) ) {
$state = $regs[1];
}
if( $city!='' && $state!='' ){
$location = $city . ', ' . $state;
return $location;
}else{
return $default;
}
}
Reference URL
function getMSIE6() {
$userAgent = strtolower($_SERVER["HTTP_USER_AGENT"]);
if (ereg("msie 6", $userAgent) || ereg("msie 5", $userAgent)) {
return true;
}
return false;
}
The HTTP_X_REQUESTED_WITH header is sent by all recent browsers that support AJAX requests.
if ( !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' )
{
# Ex. check the query and serve requested data
}
This snippet displays a nice list of all submitted data in a transparent box on the top left. Put this snippet preferable directly after <body>.
The box has some basic styling applied so that it will display a dark fixed box on the top left of the document that will automaticly show a scroll-bar if it becomes too long.
<div style="position:fixed; top:0; left: 0; width: 400px; background: rgb(0,0,0,0); background: rgba(0,0,0,0.8); color: green; margin:0px; padding:5px; max-height: 90%; overflow-y:auto;">
<h2 style="margin:0px;color:white;">$ HEADERS:</h2>
<h3 style="margin:5px;color:white;">GET</h3>
<?php
//var_dump($_GET);
foreach($_GET as $name=>$value) {
echo $name." => ";
echo $value."<br />";
}
?>
<h3 style="margin:5px;color:white;">POST</h3>
<?php
//var_dump($_POST);
foreach($_POST as $name=>$value) {
echo $name." => ";
echo $value."<br />";
}
?></div>
When you do an AJAX request on a website, the URL you request from needs to reside on the same domain as where the request was made from. This is a security restriction imposed by the browser. There is a way to sneak around this by using a bit of a "man in the middle" approach.
PHP, being a server-side language, has the ability to pull content from any URL. So a PHP file can become the man in the middle. The contents of the PHP file can be set up to accept a URL as a parameter and then return the contents of that URL.
<?php
echo file_get_contents($_GET['url']);
// WARNING: You REALLY should write something to whitelist or otherwise limit what the function will accept, or it could be a security danger to your server (people could read any file).
?>
With that in place, we can do an AJAX request directly to that URL, passing it the URL we actually want the data from as a parameter. See how we are passing "http://google.com" as data below.
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js?ver=1.3.2'></script>
<script type='text/javascript'>
$(function() {
$.ajax({
type: "GET",
dataType: 'html',
data: 'url=http://google.com',
url: 'get.php',
success: function(data){
// Yah! Do something cool with data
},
error: function(){
// Boo! Handle the error.
}
});
});
</script>
This is an extremely simple example. If you are interested in a more robust version, check out the Simple PHP Proxy.
Displays a selected chunk of an image. In the example provided, the upper left 100px x 100px are shown.
<?php
$filename= "test.jpg";
list($w, $h, $type, $attr) = getimagesize($filename);
$src_im = imagecreatefromjpeg($filename);
$src_x = '0'; // begin x
$src_y = '0'; // begin y
$src_w = '100'; // width
$src_h = '100'; // height
$dst_x = '0'; // destination x
$dst_y = '0'; // destination y
$dst_im = imagecreatetruecolor($src_w, $src_h);
$white = imagecolorallocate($dst_im, 255, 255, 255);
imagefill($dst_im, 0, 0, $white);
imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
header("Content-type: image/png");
imagepng($dst_im);
imagedestroy($dst_im);
?>
Regular expression function that replaces spaces between words with hyphens.
<?php
function create_slug($string){
$slug=preg_replace('/[^A-Za-z0-9-]+/', '-', $string);
return $slug;
}
echo create_slug('does this thing work or not');
//returns 'does-this-thing-work-or-not'
?>
function MakeUnique($length=16) {
$salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$len = strlen($salt);
$makepass = '';
mt_srand(10000000*(double)microtime());
for ($i = 0; $i < $length; $i++) {
$makepass .= $salt[mt_rand(0,$len - 1)];
}
return $makepass;
}
These can be useful for embedding images into HTML/CSS/JS to save on HTTP requests, at the cost of maintainability. More information. There are online tools to do it, but if you want your own very simple utility, here's some PHP to do it:
function data_uri($file, $mime) {
$contents=file_get_contents($file);
$base64=base64_encode($contents);
echo "data:$mime;base64,$base64";
}
$execution_time = microtime(); # Start counting
# Your code
$execution_time = microtime() - $execution_time;
$execution_time = sprintf('It took %.5f sec', $execution_time);
Give function hex code (e.g. #eeeeee), returns array of RGB values.
function hex2rgb( $colour ) {
if ( $colour[0] == '#' ) {
$colour = substr( $colour, 1 );
}
if ( strlen( $colour ) == 6 ) {
list( $r, $g, $b ) = array( $colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5] );
} elseif ( strlen( $colour ) == 3 ) {
list( $r, $g, $b ) = array( $colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2] );
} else {
return false;
}
$r = hexdec( $r );
$g = hexdec( $g );
$b = hexdec( $b );
return array( 'red' => $r, 'green' => $g, 'blue' => $b );
}
Easy way to turn a CSV file into a parseable array.
<?php
$str="foo,bar,baz,bat";
$arr=explode(",",$str);
// print_r($arr);
?>
Technique #1
function br2newline( $input ) {
$out = str_replace( "<br>", "\n", $input );
$out = str_replace( "<br/>", "\n", $out );
$out = str_replace( "<br />", "\n", $out );
$out = str_replace( "<BR>", "\n", $out );
$out = str_replace( "<BR/>", "\n", $out );
$out = str_replace( "<BR />", "\n", $out );
return $out;
}
Converts a break tag to a newline - no matter what kind of HTML is being processed.
Technique #2
function br2nl( $input ) {
return preg_replace('/<br(\s+)?\/?>/i', "\n", $input);
}
For instance, if you want to use a string as part of a URL but need to make it safe for that kind of use.
function replace_accents($str) {
$str = htmlentities($str, ENT_COMPAT, "UTF-8");
$str = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/','$1',$str);
return html_entity_decode($str);
}
<?php
/*
This code by Chris Coyier
*/
$i = 0; // counter to be used later;
?>
Comments in PHP can be between /* */ markings (useful for multiple line comments) or after // markings (for single lines only).
Variables that are submitted via web forms always need to be cleaned/sanitized before use in any way, to prevent against all kinds of different malicious intent.
Technique #1
function clean($value) {
// If magic quotes not turned on add slashes.
if(!get_magic_quotes_gpc())
// Adds the slashes.
{ $value = addslashes($value); }
// Strip any tags from the value.
$value = strip_tags($value);
// Return the value out of the function.
return $value;
}
$sample = "<a href='#'>test</a>";
$sample = clean($sample);
echo $sample;
Performs a cURL-Request to check, if a website exists / is online
Technique #1
<?php
if (isDomainAvailible('http://www.css-tricks.com'))
{
echo "Up and running!";
}
else
{
echo "Woops, nothing found there.";
}
//returns true, if domain is availible, false if not
function isDomainAvailible($domain)
{
//check, if a valid url is provided
if(!filter_var($domain, FILTER_VALIDATE_URL))
{
return false;
}
//initialize curl
$curlInit = curl_init($domain);
curl_setopt($curlInit,CURLOPT_CONNECTTIMEOUT,10);
curl_setopt($curlInit,CURLOPT_HEADER,true);
curl_setopt($curlInit,CURLOPT_NOBODY,true);
curl_setopt($curlInit,CURLOPT_RETURNTRANSFER,true);
//get answer
$response = curl_exec($curlInit);
curl_close($curlInit);
if ($response) return true;
return false;
}
?>
View Demo
Technique #2
<?php
function Visit($url){
$agent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";$ch=curl_init();
curl_setopt ($ch, CURLOPT_URL,$url );
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch,CURLOPT_VERBOSE,false);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch,CURLOPT_SSLVERSION,3);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
$page=curl_exec($ch);
//echo curl_error($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300) return true;
else return false;
}
if (Visit("http://www.google.com"))
echo "Website OK"."n";
else
echo "Website DOWN";
?>
Technique #3
<?php
ini_set("default_socket_timeout","05");
set_time_limit(5);
$f=fopen("http://www.css-tricks.com","r");
$r=fread($f,1000);
fclose($f);
if(strlen($r)>1) {
echo("<span class='online'>Online</span>");
}
else {
echo("<span class='offline'>Offline</span>");
}
?>
If the file name exists, returns new file name with _number appended so you don't overwrite it.
function file_newname($path, $filename){
if ($pos = strrpos($filename, '.')) {
$name = substr($filename, 0, $pos);
$ext = substr($filename, $pos);
} else {
$name = $filename;
}
$newpath = $path.'/'.$filename;
$newname = $filename;
$counter = 0;
while (file_exists($newpath)) {
$newname = $name .'_'. $counter . $ext;
$newpath = $path.'/'.$newname;
$counter++;
}
return $newname;
}
Example returns:
myfile.jpg
myfile_0.jpg
myfile_1.jpg