<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Dev Scene &#187; Tutorials</title>
	<atom:link href="http://www.thedevscene.com/category/tutorials/feed" rel="self" type="application/rss+xml" />
	<link>http://www.thedevscene.com</link>
	<description>News, Tutorials &#38; Tools....</description>
	<lastBuildDate>Tue, 20 Jul 2010 15:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>How We Built GottaLoveBacon.com Using Twitter, PHP And YQL</title>
		<link>http://www.thedevscene.com/tutorials/how-we-built-gottalovebacon-com-using-twitter-php-and-yql</link>
		<comments>http://www.thedevscene.com/tutorials/how-we-built-gottalovebacon-com-using-twitter-php-and-yql#comments</comments>
		<pubDate>Sat, 23 Jan 2010 07:08:09 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://www.thedevscene.com/?p=4751</guid>
		<description><![CDATA[I love Yahoo's Development Tools, especially their Yahoo Query Language (YQL). That combined with other services such as Twitter, make it easy to aggregate data to other website. And today I'm going to show you how to use YQL, PHP and Twitter Search to build a neat little website.]]></description>
			<content:encoded><![CDATA[<p>I love Yahoo&#8217;s Development Tools, especially their Yahoo Query Language (YQL). That combined with other services such as Twitter, make it easy to aggregate data to other website.</p>
<h2>What is YQL?</h2>
<p>Web apps and web services multiply like rabbits. They’re all fun to play with (like rabbits) and fun to integrate into other projects (unlike rabbits). But learning a new API every other day isn’t feasible or fun. And that’s the problem the Yahoo Query Language (YQL) is out to solve.</p>
<p>Think of YQL as the API for the web, the one API to rule them all. It’s not a hard one to learn, so let’s get you up to speed right now!</p>
<p>In this example, I&#8217;m going to show you how to use PHP, YQL, and Twitter to build a website like &#8220;<a href="http://www.gottalovebacon.com">GottaLoveBacon..com</a>&#8221;</p>
<h2>Let&#8217;s Get Started</h2>
<p>To start, we want to set up a database:</p>
<pre><code>
CREATE TABLE `tweets` (
 `id` bigint(24) NOT NULL,
 `data` mediumtext NOT NULL,
 `created_at` varchar(150) NOT NULL,
 PRIMARY KEY  (`id`),
 KEY `created_at` (`created_at`),
 FULLTEXT KEY `data` (`data`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
</code></pre>
<p>Now, here&#8217;s the YQL query that you use:</p>
<pre><code>
use 'http://www.icanhaslayout.com/twitter.search.xml' as twitter.search;
select * from twitter.search where q='#bacon';
</core></pre>
<p>If you go to the <a href="http://developer.yahoo.com/yql/console">YQL console</a> and run this query, it will return the 50 most recent search results.</p>
<h2>The Code</h2>
<p>Now, set up a functions.php file, to keep your functions in:</p>
<pre><code>
&lt;?php
$mysqlserver = "localhost";
$mysqluser = "change me";
$mysqlpass = "change me";
$mysqldb = "gottalovebacon";
function time_passed($t1, $t2){
	if($t1 > $t2){
		$time1 = $t2;
		$time2 = $t1;
	}else{
		$time1 = $t1;
		$time2 = $t2;
	}
	$diff = array('years' => 0,'months' => 0,'weeks' => 0,'days' => 0,'hours' => 0,'minutes' => 0,'seconds' =>0);
	$units = array('years','months','weeks','days','hours','minutes','seconds');
	foreach($units as $unit){
		while(true){
			$next = strtotime("+1 $unit", $time1);
			if($next < $time2){
				$time1 = $next;
				$diff[$unit]++;
			}else{
				break;
			}
		}
	}
	return($diff);
}
function getstuff($url){
	$curl_handle = curl_init();
	curl_setopt($curl_handle, CURLOPT_URL, $url);
	curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
	curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
	$buffer = curl_exec($curl_handle);
	curl_close($curl_handle);
	if (empty($buffer)){
		return 'Error retrieving data, please try later.';
	} else {
		return $buffer;
	}
}
</code></pre>
<p>From here, we are going to run this query in PHP, and store the results in the MySQL table. Save this file as index.php:</p>
<pre><code>
&lt;?php
require_once("functions.php");
$perpage = 50;
$dbh = mysql_connect($mysqlserver,$mysqluser,$mysqlpass);
mysql_select_db($mysqldb,$dbh);
$page = (isset($_GET['page']) ? $_GET['page'] : 1);
$searchphrase = "#bacon";
$root = 'http://query.yahooapis.com/v1/public/yql?q=';
$yql = "use 'http://www.icanhaslayout.com/twitter.search.xml' as twitter.search; select * from twitter.search where q='".$searchphrase."';";
$url = $root . urlencode($yql) . '&#038;format=json';
$search = getstuff($url);
$search = json_decode($search);
$search = $search-&gt;query-&gt;results;
foreach($search-&gt;entry as $d){
	$id = $d-&gt;id;
	$id = explode(":",$id);
	$d-&gt;id = end($id);
	$info = serialize($d);
	$sql = "INSERT INTO tweets SET id='{$d-&gt;id}',data='{$info}',created_at='{$d-&gt;published}';";
	mysql_query($sql);
}
$sql = "SELECT count(*) as cnt FROM tweets ORDER BY id DESC";
$qry = mysql_query($sql,$dbh);
$row = mysql_fetch_assoc($qry);
$total = $row['cnt'];
$start = ($page - 1) * $perpage;
$end = min( ($start + $perpage), $total );
?&gt;
&lt;div class="tweets"&gt;
&lt;?php
$sql = "SELECT * FROM tweets ORDER BY id DESC LIMIT ".$start.",".$end;
$qry = mysql_query($sql,$dbh);
while($row = mysql_fetch_assoc($qry)){
	$d-&gt;id = $row['id'];
	$d = unserialize($row['data']);
	$diff = time_passed(strtotime($d-&gt;published), strtotime('now'));
	$units = 0;
	$published = array();
	foreach($diff as $unit =&gt; $value){
		if($value != 0 &#038;&#038; $units < 2){
			if($value === 1){
				$unit = substr($unit, 0, -1);
			}
			$published[]= $value . ' ' .$unit;
			++$units;
		}
	}
	$published = implode(', ',$published);
	$published .= ' ago';
	$d-&gt;profile_image_url = $d-&gt;link[1]-&gt;href;
	$d-&gt;from_user = $d-&gt;author-&gt;uri;
	$d-&gt;from_user = explode("/",$d-&gt;from_user);
	$d-&gt;from_user = end($d-&gt;from_user);
?&gt;
	&lt;div class="tweet"&gt;
		&lt;div class="twitter_avatar"&gt;&lt;img src="&lt;?php echo $d-&gt;profile_image_url; ?&gt;" alt="" /&gt;&lt;/div&gt;
		&lt;p&gt;&lt;?php echo preg_replace('/(^|\s)@(\w+)/','\1&lt;a href="http://twitter.com/\2"&gt;@\2&lt;/a&gt;', $d-&gt;title);
?&gt;
		&lt;em&gt;by&lt;/em&gt; &lt;a href="http://twitter.com/&lt;?php echo $d-&gt;from_user; ?&gt;"&gt;&lt;?php echo $d-&gt;from_user;
?&gt;&lt;/a&gt;
		&lt;?php echo $published; ?&gt; &lt;em&gt;from&lt;/em&gt; &lt;?php echo html_entity_decode($d-&gt;source); ?&gt; |
		&lt;a href="http://twitter.com/&lt;?=$d-&gt;from_user?&gt;/status/&lt;?=$d-&gt;id?&gt;"&gt;view&lt;/a&gt;&lt;/p&gt;
	&lt;/div&gt;
&lt;?php
}
?&gt;
&lt;/div&gt;
&lt;ul class="pagination"&gt;
&lt;?php
	if($page == 0){$page = 1;}
	for($i = 1;$i <= ceil($total/$perpage);$i++){	?&gt;
		&lt;li class="&lt;?=($i == $page ? "active" : null)?&gt;"&gt;&lt;a title="Goto page &lt;?=$i?&gt;" href="index.php?page=&lt;?=$i?&gt;"&gt;&lt;?=$i?&gt;&lt;/a&gt;&lt;/li&gt;
&lt;?php	}	?&gt;
&lt;/ul&gt;
&lt;?php
mysql_close($dbh);
?&gt;
</code></pre>
<p>And that's it. You can change the <strong>#bacon</strong> to anything you want it to search for, and you can also play with the other twitter queries to look at doing searches via YQL, or even combine web services to add more features, like geolocation, but this is about 10 minutes work to do this so far, and it seemed a fun, cool topic to throw out to you guys.</p>
<p class="text-align:center;"><a class="button" href="http://www.thedevscene.com/wp-content/uploads/2010/01/gottalovebacon.com_.zip">Download Files</a>  <a class="button" href="http://www.gottalovebacon.com" target="_blank">View The Site</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/how-we-built-gottalovebacon-com-using-twitter-php-and-yql/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Build a simple Contact Us form in PHP</title>
		<link>http://www.thedevscene.com/tutorials/build-simple-contact-form-php</link>
		<comments>http://www.thedevscene.com/tutorials/build-simple-contact-form-php#comments</comments>
		<pubDate>Tue, 01 Sep 2009 15:21:31 +0000</pubDate>
		<dc:creator>Guest User</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=4612</guid>
		<description><![CDATA[Today, we are going to learn, step by step, how to create a &#8220;Contact Us&#8221; web form in PHP that will send us an email with a message from our visitors. We will also do a little server side validation to avoid spam and other unwanted situations. We will start by creating a web form [...]]]></description>
			<content:encoded><![CDATA[<p>Today, we are going to learn, step by step, how to create a &#8220;Contact Us&#8221; web form in PHP that will send us an email with a message from our visitors. We will also do a little server side validation to avoid spam and other unwanted situations. We will start by creating a web form which will collect the data from our visitors and pass it onto a script which will pass it through a validation process and than, if successfull, send us the email. Let&#8217;s call our page &#8220;index.php&#8221; and paste the following code in it.</p>
<p>This will be our web form.</p>
<pre><code>
&lt;link href="css/style.css" rel="stylesheet" type="text/css" /&gt;
&lt;?php
$status = $_GET['status'];
if($status=="1") {
   echo '&lt;div class="successAlert"
   style="width:560px; margin:auto"&gt;
   Message successfully sent!&lt;/div&gt;';
   } elseif ($status=="0") {
   echo '&lt;div class="warningAlert"
   style="width:560px; margin:auto"&gt;
   Your message was not sent. Please check your input!&lt;/div&gt;';
   } else {
   echo"";
   }
?&gt;
&lt;div class="container"&gt;
&lt;div class="content"&gt;
  &lt;div class="shape"&gt;
    &lt;div class="header"&gt;Contact us&lt;/div&gt;
            &lt;form method="post" id="form1" class="form" action="send_email.php"&gt;
              &lt;table align="center" cellpadding="2" cellspacing="0"&gt;
                &lt;tr&gt;
                  &lt;td&gt;&lt;label for="name"&gt;&lt;span class="pintext"&gt;
                  Your name&lt;/span&gt;&lt;/label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;div align="left" class="string"&gt;
                  &lt;input class="name" type="text" name="name" id="name" size="32" /&gt;
                  &lt;/div&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
                &lt;tr&gt;
                  &lt;td&gt;&lt;label for="email"&gt;&lt;span  class="pintext"&gt;
                   Your email&lt;/span&gt;&lt;/label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;div align="left" class="string"&gt;
                  &lt;input class="email" type="text" name="email" id="email" size="32" /&gt;
                  &lt;/div&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
                &lt;tr&gt;
                  &lt;td&gt;&lt;label for="message"&gt;&lt;span  class="pintext"&gt;
                  Your message&lt;/span&gt;&lt;/label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;div align="left" class="string_textarea"&gt;
                  &lt;textarea name="message" cols="24" rows="5" class="textarea" id="message"&gt;
                  &lt;/textarea&gt;&lt;/div&gt;
                  &lt;div align="right" class="footer_textarea"&gt;&lt;/div&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
                &lt;tr&gt;
                  &lt;td colspan="2"&gt;&lt;div align="right"&gt;
                  &lt;input class="buttons" type="submit" name="Send message"
                  id="Send message" value="Send message →" /&gt;&lt;/div&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/table&gt;
            &lt;/form&gt;
     &lt;/div&gt;
  &lt;/div&gt;
</code></pre>
<p>You will notice that we some css classes already defined so what we miss in this form is the css file. We also have some lines of PHP which will tell the visitor if the email was sent or something was wrong. We will create a new stylesheet and call it &#8220;style.css&#8221; and place it inside a new folder called &#8220;css&#8221;. It&#8217;s good to keep all things organized and place everything where it should be placed. Our site will get bigger and bigger as time goes by and it will be harder to edit and tune up things if we&#8217;re not organized. Paste the following css code into our styles page:</p>
<pre><code>
.container {
  border:1px dashed #cfcfcf;
  margin:auto;
  margin-top: 20px;
  line-height:18px;
  background:#fff;
  padding:4px;
  width:580px
}
.content {
  background-image:url(../images/b.gif);padding:10px;
}
.shape {
  margin: 0px 6px 6px 6px;
  border: 10px solid #fff;
  background: #fbfaf8;
  line-height: 1.2em;
  filter:progid:DXImageTransform.Microsoft.Shadow
  (color='#e2decd', Direction=135, Strength=9);
}
.header {
  font:bold 12px trebuchet ms, lucida grande, verdana, arial, sans-serif;
  color:#fff;
  font-size:18px;
  padding-top:4px;
  padding-bottom:4px;
  background-color: #EDCC9A;
  margin-bottom:10px;
  text-align:center;
 }
.pintext {
  color:#666;
  font:bold 16px trebuchet ms,lucida grande,verdana,arial,sans-serif;
}
.buttons {
  background: #e3e3db;
  font-size:12px;
  color: #989070;
  padding: 6px 14px;
  border-width: 2px;
  border-style: solid;
  border-color: #fff #d8d8d0 #d8d8d0 #fff;
  text-decoration: none;
  text-transform:uppercase;
  font-weight:bold;
}
.name {
  background-image: url(../images/name.png);
  background-repeat: no-repeat;
  background-position:left;
  padding-left:19px;
  background-color: #fffff0;
  margin-top: 7px;
  margin-left:15px;
  border:0px none #F11F1F;
  font:normal 18px Arial;
  color: #999999;
}
.email {
  background-image: url(../images/email.png);
  background-repeat: no-repeat;
  background-position:left;
  padding-left:19px;
  background-color: #fffff0;
  margin-top: 7px;
  margin-left:15px;
  border:0px none #F11F1F;
  font:normal 18px Arial;
  color: #999999;
}
.string {
  background-image: url(../images/big_searchbg.gif);
  width: 346px;
  height: 38px;
  border:0px;
}
.textarea {
  background-image: url(../images/bg_textarea.gif);
  margin-top:10px;
  background-color: #fffff0;
  width: 341px;
  border:0px none #F11F1F;
  font:normal 18px Arial;
  color: #999999;
  padding: 15px;
}
.footer_textarea {
  background-image: url(../images/f_textarea.gif);
  background-position: bottom;
  background-repeat: no-repeat;
  width: 346px;
  height: 12px;
  border:0px;
}
.string_textarea {
  background-image: url(../images/top_textarea.gif);
  background-position: top;
  background-repeat: no-repeat;
  width: 346px;
  border:0px;
}
.warningAlert,.successAlert,.errorAlert {
  text-align:center;
  font:italic normal 100% georgia,times,serif;
  padding:9px
}
.successAlert a,.warningAlert a,.errorAlert a {
  font-weight:700
}
.successAlert {
  color:#333;
  border:3px solid #8fc15e;
  background:#edf9d9
}
.successAlert a {
  color:#360 !important
}
.warningAlert,.errorAlert {
  color:#000;
  border:3px solid #cd6531;
  background:#ffe6cd
}
.warningAlert a,.errorAlert a {
  color:#b46131 !important
}
</code></pre>
<p>We&#8217;re almost done. We have the page that our visitors will use to submit data so what we need right now is a script that will validate this input and process it. Let&#8217;s create a new file and call it &#8220;send_email.php&#8221;. Paste this code inside it:</p>
<pre><code>
$site_name = "your site name here";
$admin_email = "yourEmail@whatever.com";
function check_email_address($email) {
  if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
    header("Location: index.php?status=0");
  }
  $email_array = explode("@", $email);
  $local_array = explode(".", $email_array[0]);
  for ($i = 0; $i &lt; sizeof($local_array); $i++) {
     if (!ereg("^(([A-Za-z0-9!#$%&amp;'*+/=?^_`{|}~-][A-Za-z0-9!#$%&amp;'*+/=?^_`{|}~\.-] {0,63})|(\"[^(\\|\")]{0,62}\"))$", $local_array[$i])) {
       header("Location: index.php?status=0");
    }
  }
  if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) {
    $domain_array = explode(".", $email_array[1]);
    if (sizeof($domain_array) &lt; 2) {
         die ("Invalid email address");
    }
    for ($i = 0; $i &lt; sizeof($domain_array); $i++) {
      if (!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$",
      $domain_array[$i])) {
         header("Location: index.php?status=0");
      }
    }
  }
  return $email;
}

function escape_val($string) {
	$string = str_replace(array('"',"&lt;","&gt;"), array(""","&lt;","&gt;"), $string);
	return $string;
}

$check_email = check_email_address($_REQUEST['email']);
$name = escape_val($_REQUEST['name']);
$message = escape_val($_REQUEST['message']);
$time = date('l dS \of F Y h:i:s A');
$email_subject = "New contact message from ".$site_name."";

if(mail($admin_email,$email_subject,$message,
"From:$check_email,Reply-to:$check_email")) {
header("Location: index.php?status=1");
exit;
} else {
header("Location: index.php?status=0");
}
</code></pre>
<p>This page will grab the data that was submited via our form and return to our index.php page with 2 possible statuses: 0 for &#8220;something&#8217;s wrong&#8221; and 1 for &#8220;ok! email sent&#8221;. If you go back and study &#8220;index.php&#8221; you will notice this php code which will tell our visitor if the email was successfull or not:</p>
<pre><code>
$status = $_GET['status'];
if($status=="1") {
echo '&lt;div class="successAlert" style="width:560px; margin:auto"&gt;
Message successfully sent!&lt;/div&gt;';
} elseif ($status=="0") {
echo '&lt;div class="warningAlert" style="width:560px; margin:auto"&gt;
Your message was not sent. Please check your input!&lt;/div&gt;';
} else {
echo"";
}
</code></pre>
<p class="text-align:center;"><a class="button" href="http://www.thedevscene.com/examples/email/">View A Demo</a> <a class="button" href="http://www.thedevscene.com/wp-content/uploads/2009/06/email.zip">Download Files</a></p>
<p><em>Please note, the demo does not send any mail, as it is just to show how it looks.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/build-simple-contact-form-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build a simple login script with PHP and MySQL</title>
		<link>http://www.thedevscene.com/tutorials/build-simple-login-script-php-mysql</link>
		<comments>http://www.thedevscene.com/tutorials/build-simple-login-script-php-mysql#comments</comments>
		<pubDate>Mon, 01 Jun 2009 15:47:15 +0000</pubDate>
		<dc:creator>Guest User</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=4607</guid>
		<description><![CDATA[Programming a php login script can be a real pain. It has to be well coded, unique and, most of all, secure. We will pass all the mentioned aspects of a php login system in this tutorial by actually building one. Today I&#8217;m going to teach you how to write a good login script with [...]]]></description>
			<content:encoded><![CDATA[<p>Programming a php login script can be a real pain. It has to be well coded, unique and, most of all, secure. We will pass all the mentioned aspects of a php login system in this tutorial by actually building one. Today I&#8217;m going to teach you how to write a good login script with user levels (admin, members, managers etc.), with forgot password included, user activation upon registering and just about everything that is supposed to be included in a good login system.</p>
<p>To start with this we will need a table in our database which will hold the users data:</p>
<pre><code>CREATE TABLE `users` (
  `ID` int(11) NOT NULL auto_increment,
  `Username` varchar(55) NOT NULL,
  `Password` varchar(55) NOT NULL,
  `Temp_pass` varchar(55) default NULL,
  `Temp_pass_active` tinyint(1) NOT NULL default '0',
  `Email` varchar(100) NOT NULL,
  `Active` int(11) NOT NULL default '0',
  `Level_access` int(11) NOT NULL default '2',
  `Random_key` varchar(32) default NULL,
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `Username` (`Username`),
  UNIQUE KEY `Email` (`Email`)
) ENGINE=MyISAM;</code></pre>
<p>As you can see from the above schema, I complicated things a little bit by adding some extra fields: level access, temporarily password, temp. password active and the random key. With the help of this structure and the stored data we are going to be able to create a complex php login script.</p>
<p>I&#8217;ve seen a lot of bad code in the registration page of other websites and especially on pages that have forms and process inputs. On my opinion, the most dangerous parts of websites, that need extra security and extra attention are pages with SQL statements that rely on data provided via $_GET, $_REQUEST, $_POST which can very well be traduced to forms and dynamic url&#8217;s.</p>
<p>I will take a good BAD example of not processing forms and I hope it will give you a good idea of the way you&#8217;re supposed to run things. Let&#8217;s stay on the same page and talk about the user registration form. I can have the following html:</p>
<pre><code>
&lt;form action="register.php" method="post"&gt;
&lt;input type="text" id="username" name="username" size="32" value="" /&gt;
&lt;input type="password" id="password" name="password" size="32" value="" /&gt;
&lt;input type="text" id="email" name="email" size="32" value="" /&gt;
&lt;input type="hidden" id="active" name="active" size="32" value="0" /&gt;
&lt;input type="hidden" id="level_access" name="level_access" size="32" value="2" /&gt;
&lt;input type="submit" name="register" value="register" /&gt;
&lt;/form&gt;
</code></pre>
<p>I&#8217;m sure that many of you have already seen the problem. A lot of people actually use this method which is very bad. As you can see in the above MySql schema, for the field `Active` I have the default value to 0. Mysql will add that to every new record UNLESS you specify something else. Not everyone builds sql tables the same way. A lot of websites still work with this stupid criteria. If it&#8217;s input hidden than it&#8217;s hidden and nobody will see it. Wrong, someone could download your page, save it to a html file, change the Active from 0 to 1, create a nice loop and there you have it, you could wake up tomorrow with 1000 new members <img src='http://www.thedevscene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>My first point for this tutorial: extra safety when building forms. Show only what is needed. I can set the default value to 0 in MySql and I can safely delete that hidden input which is supposed to store the value. The same thing is valid with the `level_access` field which is even more dangerous. You might share your admin with unwanted members.</p>
<p>With all that being said, let&#8217;s compose our registration page:</p>
<pre><code>
&lt;?php
require_once('db.php');
include('functions.php');
if(isset($_POST['register'])){
  if($_POST['username']!='' &#038;&#038; $_POST['password']!='' &#038;&#038; $_POST['password']==$_POST['password_confirmed'] &#038;&#038; $_POST['email']!='' &#038;&#038; valid_email($_POST['email'])==TRUE &#038;&#038; checkUnique('Username', $_POST['username'])==TRUE &#038;&#038; checkUnique('Email', $_POST['email'])==TRUE) {
    $query = mysql_query("INSERT INTO users (`Username` , `Password`, `Email`, `Random_key`) VALUES ('".mysql_real_escape_string($_POST['username'])."', '".mysql_real_escape_string(md5($_POST['password']))."', '".mysql_real_escape_string($_POST['email'])."', '".random_string('alnum', 32)."')") or die(mysql_error());
    $getUser = mysql_query("SELECT ID, Username, Email, Random_key FROM users WHERE Username = '".mysql_real_escape_string($_POST['username'])."'") or die(mysql_error());
    if(mysql_num_rows($getUser)==1){
      $row = mysql_fetch_assoc($getUser);
      $headers =   'From: webmaster@ourdomainhere.com' . "\r\n" .
            'Reply-To: webmaster@ourdomainhere.com' . "\r\n" .
            'X-Mailer: PHP/' . phpversion();
      $subject = "Activation email from ourdomainhere.com";
      $message = "Dear ".$row['Username'].", this is your activation link to join our website. In order to confirm your membership please click on the following link: http://www.ourdomainhere.com/confirm.php?ID=".$row['ID']."&amp;key=".$row['Random_key']." Thank you for joining";
      if(mail($row['Email'], $subject, $message, $headers)){
        $msg = 'Account created. Please login to the email you provided during registration and confirm your membership.';
      }else {
        $error = 'I created the account but failed sending the validation email out. Please inform my boss about this cancer of mine';
      }
    }else {
      $error = 'You just made possible the old guy (the impossible). Please inform my boss in order to give you the price for this.';
    }
  }else {
    $error = 'There was an error in your data. Please make sure you filled in all the required data, you provided a valid email address and that the password fields match';
  }
}
?&gt;
&lt;?php if(isset($error)){ echo $error;}?&gt;
&lt;?php if(isset($msg)){ echo $msg;} else {?&gt;
&lt;form action="&lt;?=$_SERVER['PHP_SELF']?&gt;" method="post"&gt;
Username: &lt;input type="text" id="username" name="username" size="32" value="&lt;?php if(isset($_POST['username'])){echo $_POST['username'];}?&gt;" /&gt;&lt;br /&gt;
Password: &lt;input type="password" id="password" name="password" size="32" value="" /&gt;&lt;br /&gt;
Re-password: &lt;input type="password" id="password_confirmed" name="password_confirmed" size="32" value="" /&gt;&lt;br /&gt;
Email: &lt;input type="text" id="email" name="email" size="32" value="&lt;?php if(isset($_POST['email'])){echo $_POST['email'];}?&gt;" /&gt;&lt;br /&gt;
&lt;input type="submit" name="register" value="register" /&gt;&lt;br /&gt;
&lt;/form&gt;
&lt;? } ?&gt;
</code></pre>
<p>Another important aspect when building forms is the fact that people hate them. If they complete something wrong and the server comes back with an error and a new form (or the previous one but empty) they will most probably leave so this is why we have the $_POST values there, the username and email field will remain completed. The errors will be shown using $error which is visible only if is set and can be set only if something&#8217;s wrong (vicious circle huh <img src='http://www.thedevscene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) and the confirmation message will be visible (this will also make the form invisible) only in one case, one successful case.</p>
<p>Let&#8217;s take the above code step by step and try to understand it. In the first part of it we have the php code which will process our form and decide what&#8217;s next. We confirm or we throw out an error. Notice that it begins with an if statement (and I encourage you to use it in your applications to make sure all conditions are met before running something) that needs to be satisfied before we enter the details into the database. There&#8217;s an unlimited number of if&#8217;s that can be set, I just used it to make sure all fields are entered, the two passwords match each other, the username is not taken and that the email address is valid and also unique as well. If one of the above conditions is not satisfied we have an else statement to define $error and output the message. Next, we passed the first &#8220;if&#8221; and it means that everything was ok until here so we create a query to enter the details into our table &#8220;users&#8221;. Make sure you escape all variables used in a query. Also notice that I used md5 to encrypt the password before storing it into our database.</p>
<p>  It&#8217;s time to send out the confirmation email in order for our new user to verify the entered email address and activate his membership. For this step we created the `Random_key` field in our table. We need a random key generated at the time we register a new user, he won&#8217;t be able to know that key unless he opens the confirmation email. We could use the following activation schema via $_GET: confirm.php?ID=123 where ID is the unique record number of the user but that would be easy to guess. A robot could create usernames and activate them by incrementing the ID. </p>
<p>In our example, only if the ID and the Random_key is matched we update the `Active` field and set it to 1. we&#8217;re not there yet but I needed to explain everything that takes part in our code.</p>
<p>  After inserting the new member we write an extract query to get the exact data that was stored and create the activation link. We have another if statement for the email, if is sent $msg will be defined and the form will become invisible &#8211; the confirmation message is displayed. If not, there&#8217;s an else statement again to inform our visitor that something went wrong. As you can see, in my opinion, it&#8217;s good to communicate with the visitor at every step, if something&#8217;s wrong or not, show a message. Almost everything starts with an if and has an else or elseif.</p>
<p>  I think we&#8217;re done with the register page, let&#8217;s move to that confirm.php which will have to take the data, check it against the database and, based on what is stored there, decide what to do. Just like in the register page, we will start with an if statement and only if all the conditions are satisfied, we confirm that membership. </p>
<pre><code>
&lt;?php
require_once('db.php');
include('functions.php');
if($_GET['ID']!='' &#038;&#038; numeric($_GET['ID'])==TRUE &#038;&#038; strlen($_GET['key'])==32 &#038;&#038; alpha_numeric($_GET['key'])==TRUE){
  $query = mysql_query("SELECT ID, Random_key, Active FROM users WHERE ID = '".mysql_real_escape_string($_GET['ID'])."'");
  if(mysql_num_rows($query)==1){
    $row = mysql_fetch_assoc($query);
    if($row['Active']==1){
      $error = 'This member is already active !';
    }elseif($row['Random_key']!=$_GET['key']){
      $error = 'The confirmation key that was generated for this member does not match with the one entered !';
    }else{
      $update = mysql_query("UPDATE users SET Active=1 WHERE ID='".mysql_real_escape_string($row['ID'])."'") or die(mysql_error());
      $msg = 'Congratulations !  You just confirmed your membership !';
    }
  }else {
    $error = 'User not found !';
  }
}else {
  $error = 'Invalid data provided !';
}
if(isset($error)){
  echo $error;
}else {
  echo $msg;
}
?&gt;
</code></pre>
<p>Ok. Let&#8217;s split this code also. AGAIN, we filter the data and only if (yes another if statement) both the ID and random key match our criteria, we may continue; else, set a value for $error.<br />
I used 2 functions from the snippets section to make sure that the incoming ($_GET['ID']) ID has a numeric value and that our key has 32 characters (strlen($_GET['key'])) and is also alpha-numeric.</p>
<p>Here&#8217;s how the information comes in via $_GET from the confirmation link: confirm.php?ID=123&#038;key=4ytu683hbmh849f9g7hjjym78eog648. We create a SELECT query based on the ID that was provided. If the user is found (mysql_num_rows($query)==1) we continue (else: set another value for $error) with another if: if the user is already activated, set another value for $error (This member is already active !), else if the incoming key ($_GET['key']) does not match the one from our database ($row['Random_key']!=$_GET['key']) set another value for $error (The confirmation key that was generated for this member does not match with the one entered !). After this big filter, when everything is as supposed to be, do the update query and set the value to 1 which, in our case, is equal with an active member.</p>
<p>Our next task is to create the login page which will have to check the entered username and password, see what level access the user has and decide if he&#8217;s allowed to view the requested page.</p>
<pre><code>
&lt;?php
require_once('db.php');
include('functions.php');
if(isset($_POST['Login'])){
  if($_POST['username']!='' &#038;&#038; $_POST['password']!=''){
    $query = mysql_query('SELECT ID, Username, Active FROM users WHERE Username = "'.mysql_real_escape_string($_POST['username']).'" AND Password = "'.mysql_real_escape_string(md5($_POST['password'])).'"');
    if(mysql_num_rows($query) == 1){
      $row = mysql_fetch_assoc($query);
      if($row['Active'] == 1){
        $_SESSION['user_id'] = $row['ID'];
        $_SESSION['logged_in'] = TRUE;
        header("Location: members.php");
      }else {
        $error = 'Your membership was not activated. Please open the email that we sent and click on the activation link';
      }
    }else {
      $error = 'Login failed !';
    }
  }else {
    $error = 'Please user both your username and password to access your account';
  }
}
?&gt;
&lt;?php if(isset($error)){ echo $error;}?&gt;
&lt;form action="&lt;?=$_SERVER['PHP_SELF']?&gt;" method="post"&gt;
&lt;input type="text" id="username" name="username" size="32" value="" /&gt;
&lt;input type="password" id="password" name="password" size="32" value="" /&gt;
&lt;input type="submit" name="Login" value="Login" /&gt;
&lt;/form&gt;
</code></pre>
<p>The above code does a simple task. After submitting the form it again checks if the values are not empty (else defines $error) and continues to the sql select statement. If the number of records that return, based on the provided username and password, is equal to 1 (it has to but we just make sure) we move forward and check to see if the user has activated his membership ($row['Active'] == 1). If it&#8217;s active, we set $_SESSION['user_id'] with the ID record of our member that has just successfully logged in (members.php will be the default redirect on success page). As always we have else statements to define $error and communicate with our visitor in case something goes wrong.</p>
<p>Our next step is to create a forgot password page. The plan is to generate a temporarily password for the requested username and make it active after the request but NOT override the actual password. If the confirmation (of password reset) is received and the link clicked, we update the users table and set the temp. password active field to 0 since it&#8217;s confirmed. You can only reset it once per request. A new request is needed for a new change. This sounds a little complicated but if you will play with this password reset page I&#8217;m sure it will be more than self explanatory so let&#8217;s start coding this little page.</p>
<pre><code>
&lt;?php
require_once('db.php');
include('functions.php');
if(isset($_POST['Submit'])){
  if($_POST['email']!='' &#038;&#038; valid_email($_POST['email'])==TRUE){
    $getUser = mysql_query('SELECT ID, Username, Temp_pass, Email FROM users WHERE Email = "'.mysql_real_escape_string($_POST['email']).'"');
    if(mysql_num_rows($getUser)==1){
      $temp_pass = random_string('alnum', 12);
      $row = mysql_fetch_assoc($getUser);
      $query = mysql_query("UPDATE users SET Temp_pass='".$temp_pass."', Temp_pass_active=1 WHERE `Email`='".mysql_real_escape_string($row['Email'])."'");
      $headers =   'From: webmaster@ourdomainhere.com' . "\r\n" .
        'Reply-To: webmaster@ourdomainhere.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();
      $subject = "Password Reset Request";
      $message = "Dear ".$row['Username'].", Someone (presumably you), has requested a password reset. We have generated a new password for you to access our website:  $temp_pass . To confirm this change and activate your new password please follow this link to our website: http://www.ourdomainhere.com/confirm_password.php?ID=".$row['ID']."&#038;new=".$temp_pass.". Don't forget to update your profile as well after confirming this change and create a new password. If you did not initiate this request, simply disregard this email, and we're sorry for bothering you.";
      if(mail($row['Email'], $subject, $message, $headers)){
        $msg = 'Password reset request sent. Please check your email for instructions.';
      }else {
        $error = 'Failed sending email';
      }
    }else {
      $error = 'There is no member to match your email.';
    }
  }else {
    $error = 'Invalid email !';
  }
}
?&gt;
&lt;?php if(isset($error)){ echo $error;}?&gt;
&lt;?php if(isset($msg)){ echo $msg;} else {//if we have a mesage we don't need this form again.?&gt;
&lt;form action="&lt;?=$_SERVER['PHP_SELF']?&gt;" method="post"&gt;
&lt;input type="text" id="email" name="email" size="32" value="" /&gt;
&lt;input type="submit" name="Submit" value="Submit" /&gt;
&lt;/form&gt;
&lt;? } ?&gt;
</code></pre>
<p>Inspecting the above code you will see that we need to create confirm_password.php in order to verify the new password and update the users info if confirmed. It has to see if there is an active temporarily password for that user and if the $_GET info matches the data stored in our database.</p>
<pre><code>
&lt;?php
require_once('db.php');
include('functions.php');
$query = mysql_query("SELECT * FROM users WHERE ID = '".mysql_real_escape_string($_GET['ID'])."'");
if(mysql_num_rows($query)==1){
  $row = mysql_fetch_assoc($query);
  if($row['Temp_pass']==$_GET['new'] &#038;&#038; $row['Temp_pass_active']==1){
    $update = mysql_query("UPDATE users SET Password = '".md5(mysql_real_escape_string($_GET['new']))."', Temp_pass_active=0 WHERE ID = '".mysql_real_escape_string($_GET['ID'])."'");
    $msg = 'Your new password has been confirmed. You may login using it.';
  }else{
    $error = 'The new password is already confirmed or is incorrect';
  }
}else {
  $error = 'You are trying to confirm a new password for an unexisting member';
}
if(isset($error)){
  echo $error;
}else {
  echo $msg;
}
?&gt;
</code></pre>
<p>We&#8217;re almost finished. We need to create one more function which will check the level access. Maybe you want to restrict page access based on user levels.</p>
<pre><code>
&lt;?php
function checkLogin($levels){
  if(!$_SESSION['logged_in']){
    $access = FALSE;
  }else {
    $kt = split(' ', $levels);
    $query = mysql_query('SELECT Level_access FROM users WHERE ID = "'.mysql_real_escape_string($_SESSION['user_id']).'"');
    $row = mysql_fetch_assoc($query);
    $access = FALSE;
    while(list($key,$val)=each($kt)){
      if($val==$row['Level_access'])$access = TRUE;
    }
  }
  if($access==FALSE) header("Location: login.php");
}
?&gt;
</code></pre>
<p>The above function takes the allowed user levels for that page, and checks them against what&#8217;s in the database for the authenticated user. If there&#8217;s a match, we grant access, else, redirect to login.<br />
Presuming a restricted page called &#8220;members.php&#8221; where are allowed both the admin and a regular member we would use the function like this at the very beginning of the page:</p>
<pre><code>&lt;?php
session_start();
checkLogin('1 2');
?&gt;</code></pre>
<p>and for an admin:</p>
<pre><code>&lt;?php
session_start();
checkLogin('1');
?&gt;</code></pre>
<p>We don&#8217;t store information like user email, password, username etc. on the session. We will just use the ID and based on $_SESSION['user_id'] we&#8217;ll perform SQL queries to request the data when is needed. The session can also be md5 encrypted for better security.</p>
<p style="text-align:center">
  <a class="button" href="http://www.thedevscene.com/wp-content/uploads/2009/06/login1.zip">Download Files</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/build-simple-login-script-php-mysql/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create a dynamic Twitter Signature with PHP.</title>
		<link>http://www.thedevscene.com/tutorials/create-dynamic-twitter-signature-php</link>
		<comments>http://www.thedevscene.com/tutorials/create-dynamic-twitter-signature-php#comments</comments>
		<pubDate>Fri, 13 Mar 2009 20:17:05 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[GD library]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=4482</guid>
		<description><![CDATA[Today, I&#8217;m going to show you how to use PHP and it&#8217;s GD library to create a dynamic signature that you can use on forums, blogs, etc, that contains your latest tweet. This will be a simple script, you can adjust it yourself later. To begin, you&#8217;ll need a background image, we&#8217;ll use this one: [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I&#8217;m going to show you how to use PHP and it&#8217;s GD library to create a dynamic signature that you can use on forums, blogs, etc, that contains your latest tweet.</p>
<p>This will be a simple script, you can adjust it yourself later.</p>
<p>To begin, you&#8217;ll need a background image, we&#8217;ll use this one:</p>
<p><a href="http://www.quickpipe.com/examples/signa/twit.png"><img class="aligncenter" title="twitter signature background image" src="http://www.quickpipe.com/examples/signa/twit.png" alt="" width="400" height="54" /></a></p>
<p>Now, we&#8217;ll create <strong>mysig.php</strong>:</p>
<p>First, let&#8217;s go over the initial script:</p>
<pre><code>
   $name = $_GET['name'];
   $srcImage = "./twit.png";
   $im = imagecreatefrompng($srcImage);
   $res = tweetit($name,1);
   $string = $res[2].": ".$res[0];
   $timg = $res[1];
   if( !empty($timg) ){
      $timg = copyImg($timg);
      if( stristr($timg,".jpg") ){
         $stamp = imagecreatefromjpeg($timg);
      }else if( stristr($timg,".png") ){
         $stamp = imagecreatefrompng($timg);
      }
      $marge_right = 2;
      $marge_bottom = 2;
      $sx = imagesx($stamp);
      $sy = imagesy($stamp);
      imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));
   }
   $black = @imagecolorallocate ($im, 0, 0, 0);
   $white = @imagecolorallocate ($im, 255, 255, 255);
   $width = imagesx($im);
   $height = imagesy($im);
   $color = imagecolorallocate($im, 100, 100, 100);
   ImageStringWrap($im, 3, 5, 2, $string, $black,320);
   header("Content-type: image/png");
   imagepng($im);
   exit;
</code></pre>
<p>So, there are a few steps involved here, we still need to create some functions.</p>
<p>The first function, is a function called <strong>tweetit</strong>, which returns the latest tweet:</p>
<pre><code>
   function tweetit($user,$cnt = 1){
      $curl = curl_init('http://twitter.com/statuses/user_timeline/' . $user . '.xml?count='.$cnt);
      curl_setopt($curl,CURLOPT_HEADER,false);
      curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
      $twi = curl_exec($curl);
      curl_close($curl);
      $tweeters = new SimpleXMLElement($twi);
      $latesttweets = count($tweeters);
      foreach ($tweeters-&gt;status as $twit1) {
         $text = (string)$twit1-&gt;text;
         $img = (string)$twit1-&gt;user-&gt;profile_image_url;
         $name = (string)$twit1-&gt;user-&gt;screen_name;
         break;
      }
      return array( $text,$img,$name);
   }
</code></pre>
<p>Next, we have to copy the avatar for your twitter account, this will help save on bandwidth later, and also helps cut down on trying to manipulate remotely hosted images:</p>
<pre><code>
   function copyImg($url){
      $fname = explode("/",$url);
      $fname = end($fname);
      $fname = "avas/".$fname;
      if( !file_exists($fname) ){
         $curl = curl_init($url);
         curl_setopt($curl,CURLOPT_HEADER,false);
         curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
         $twi = curl_exec($curl);
         curl_close($curl);
         $fp = fopen($fname, 'w');
         fwrite($fp, $twi);
         fclose($fp);
      }
      return $fname;
   }
</code></pre>
<p>The last function, is our custom <strong>ImageStringWrap</strong> function, this function is used to split your tweet into multiple lines based on image width.</p>
<pre><code>
   function ImageStringWrap($image, $font, $x, $y, $text, $color, $maxwidth){
      $fontwidth = ImageFontWidth($font);
      $fontheight = ImageFontHeight($font);
      if ($maxwidth != NULL) {
         $maxcharsperline = floor($maxwidth / $fontwidth);
         $text = wordwrap($text, $maxcharsperline, "\n", 1);
      }
      $lines = explode("\n", $text);
      while (list($numl, $line) = each($lines)) {
         ImageString($image, $font, $x, $y, $line, $color);
         $y += $fontheight;
      }
   }
</code></pre>
<p>Now, let&#8217;s put it all together:</p>
<pre><code>
   $name = $_GET['name'];
   $srcImage = "./twit.png";
   $im    = imagecreatefrompng($srcImage);
   $res = tweetit($name,1);
   $string = $res[2].": ".$res[0];
   $timg = $res[1];
   if( !empty($timg) ){
      $timg = copyImg($timg);
      if( stristr($timg,".jpg") ){
         $stamp = imagecreatefromjpeg($timg);
      }else   if( stristr($timg,".png") ){
         $stamp = imagecreatefrompng($timg);
      }
      $marge_right = 2;
      $marge_bottom = 2;
      $sx = imagesx($stamp);
      $sy = imagesy($stamp);
      imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));
   }
   $black = @imagecolorallocate ($im, 0, 0, 0);
   $white = @imagecolorallocate ($im, 255, 255, 255);
   $width = imagesx($im);
   $height = imagesy($im);
   $color = imagecolorallocate($im, 100, 100, 100);
   ImageStringWrap($im, 3, 5, 2, $string, $black,320);
   header("Content-type: image/png");
   imagepng($im);
   exit;

   function ImageStringWrap($image, $font, $x, $y, $text, $color, $maxwidth){
      $fontwidth = ImageFontWidth($font);
      $fontheight = ImageFontHeight($font);
      if ($maxwidth != NULL) {
         $maxcharsperline = floor($maxwidth / $fontwidth);
         $text = wordwrap($text, $maxcharsperline, "\n", 1);
      }
      $lines = explode("\n", $text);
      while (list($numl, $line) = each($lines)) {
         ImageString($image, $font, $x, $y, $line, $color);
         $y += $fontheight;
      }
   }
   function tweetit($user,$cnt = 1){
      $curl = curl_init('http://twitter.com/statuses/user_timeline/' . $user . '.xml?count='.$cnt);
      curl_setopt($curl,CURLOPT_HEADER,false);
      curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
      $twi = curl_exec($curl);
      curl_close($curl);
      $tweeters = new SimpleXMLElement($twi);
      $latesttweets = count($tweeters);
      foreach ($tweeters-&gt;status as $twit1) {
         $text = (string)$twit1-&gt;text;
         $img = (string)$twit1-&gt;user-&gt;profile_image_url;
         $name = (string)$twit1-&gt;user-&gt;screen_name;
         break;
      }
      return array( $text,$img,$name);
   }
   function copyImg($url){
      $fname = explode("/",$url);
      $fname = end($fname);
      $fname = "avas/".$fname;
      if( !file_exists($fname) ){
         $curl = curl_init($url);
         curl_setopt($curl,CURLOPT_HEADER,false);
         curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
         $twi = curl_exec($curl);
         curl_close($curl);
         $fp = fopen($fname, 'w');
         fwrite($fp, $twi);
         fclose($fp);
      }
      return $fname;
   }
</code></pre>
<p>This is how the script works, you call it as follows:</p>
<pre><code>
   &lt;img src="mysig.php?name=freekrai" alt="" /&gt;
</code></pre>
<p>And you get this:</p>
<div><img src="/examples/signa/sig.php?name=freekrai" alt="" /></div>
<p>Pretty cool huh?</p>
<p>When you upload this to your site, your going to want to create a folder called &#8220;<strong>avas</strong>&#8220;, and make sure it is writable by setting it to 755 or 777, this will let you store your twitter avatars locally using the <strong>copyImg</strong> function.</p>
<div><a class="button" href="http://www.quickpipe.com/wp-content/uploads/2009/03/twittersig.zip">Download it here</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/create-dynamic-twitter-signature-php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Build your own Search Engine with BOSS</title>
		<link>http://www.thedevscene.com/tutorials/build-search-engine-boss</link>
		<comments>http://www.thedevscene.com/tutorials/build-search-engine-boss#comments</comments>
		<pubDate>Fri, 14 Nov 2008 18:07:39 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[$site]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[built-in search engine]]></category>
		<category><![CDATA[large site]]></category>
		<category><![CDATA[open search platform]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pre-existing site]]></category>
		<category><![CDATA[production search infrastructure]]></category>
		<category><![CDATA[search capabilites]]></category>
		<category><![CDATA[Search Engine]]></category>
		<category><![CDATA[search engines]]></category>
		<category><![CDATA[search experiences]]></category>
		<category><![CDATA[search index]]></category>
		<category><![CDATA[search industry]]></category>
		<category><![CDATA[search landscape]]></category>
		<category><![CDATA[web-scale search engine]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=2263</guid>
		<description><![CDATA[Back in July, Yahoo! started offering the BOSS service, an open search platform. Using the BOSS API, developers have access to Yahoo&#8217;s entire search index to create custom search engines. The goal with BOSS (Build your Own Search Service) is simple &#8212; foster innovation in the search landscape. As anyone who follows the search industry [...]]]></description>
			<content:encoded><![CDATA[<p>Back in July, Yahoo! started offering the <a href="http://developer.yahoo.com/search/boss/">BOSS</a> service, an open search platform. Using the BOSS API, developers have access to Yahoo&#8217;s entire search index to create custom search engines.</p>
<p>The goal with BOSS (Build your Own Search Service) is simple &#8212; foster innovation in the search landscape. As anyone who follows the search industry knows, the barriers to successfully building a high quality, web-scale search engine are incredibly high.</p>
<div style="text-align: center;"><a href="http://developer.yahoo.com/search/boss/"><img src="http://www.quickpipe.com/wp-content/uploads/2008/11/boss_info5.gif" alt="" width="437" height="106" /></a></div>
<p><strong>So what is BOSS?</strong><br />
BOSS is an open platform that offers programmatic access to the entire Yahoo! Search index via an API. BOSS allows developers to take advantage of Yahoo!&#8217;s production search infrastructure and technology, combine that with their own unique assets, and create their own search experiences. While search APIs have been available for some time, BOSS removes many of the usage restrictions that have prevented other companies from using them to build innovative new search engines.</p>
<p>This approach lets anyone build a search engine to their specific skills, mash the data with other sources, re-arrange results, or any other novel idea for the next big search engine. You could also easily use BOSS to add search capabilites to a pre-existing site, limiting the results to just its data.</p>
<p>For example, I recently had to create a wordpress plugin that used BOSS to search a fairly large site instead of using the built-in search engine. I&#8217;ve also set BOSS up on a couple of my other sites for searches.</p>
<p>Today, we&#8217;re going to build a simple BOSS powered search engine in PHP. To start, make sure you get an APP key from the <a href="http://developer.yahoo.com/search/boss/">BOSS website</a>, then folow the code.</p>
<p>To start, let&#8217;s enter the beginning info:</p>
<pre><code>&lt;?php
$apikey = 'YOUR-API-KEY';
$mysite = "yourdomain.com";
$plimit = 20;
?&gt;</code></pre>
<p>Replace the text that says &#8220;YOUR-API-KEY&#8221; with the API Key you get from BOSS. The next variable is called &#8220;mysite&#8221;, this lets you specify a domain that you want BOSS to search, if you don&#8217;t want to search any specific website, then leave mysite blank.</p>
<p>Another variable is called &#8220;plimit&#8221;, this lets you specify how many results to display on each page. We&#8217;ll use 20 per page here, but you can change it at anytime.</p>
<p>Now, all that&#8217;s left to do is to search:</p>
<p><strong>Finished Code:</strong></p>
<pre><code>&lt;?php
$apikey = 'YOUR-API-KEY';
$mysite = "yourdomain.com";
$plimit = 20;
$offon1 = "checked=TRUE";
$offon2 = "checked=TRUE";
if( !isset($_REQUEST['sitesearch']) ){
	$offon2 = "";
}else{
	if( empty($_REQUEST['sitesearch']) ){
		$offon1 = "";
	}else{
		$offon2 = "";
	}
}
?&gt;
&lt;br style="clear: both" /&gt;
&lt;form id="searchform" method="POST" &gt;
&lt;label for="Keywords" class="hidden"&gt;Search for:&lt;/label&gt;
&lt;input type="text" id="Keywords" name="Keywords" value="&lt;?=( isset($_REQUEST['Keywords']) ? $_REQUEST['Keywords'] : null )?&gt;"/&gt; &lt;input type="submit" class="submitButton" value="GO" id="searchsubmit" name="submit"/&gt;
&lt;?php	if($mysite != ""){	?&gt;
	&lt;br style="clear: both" /&gt;
	&lt;input type="radio" &lt;?=$offon1?&gt; value="1" name="sitesearch"/&gt;Search &lt;?=$blogname?&gt;
	&lt;input type="radio" &lt;?=$offon2?&gt; value="" name="sitesearch"/&gt;Search WWW
&lt;?php	}	?&gt;
&lt;/form&gt;
&lt;br style="clear: both" /&gt;
&lt;?php
$start = $_REQUEST['start'];
if ($_REQUEST['Keywords'] != "") {
	$thequery = urlencode($_REQUEST['Keywords']);
	if( !empty($_REQUEST['sitesearch']) &amp;&amp; $mysite != "" ){
		$site = 'site:'.$mysite;
		$url = "http://boss.yahooapis.com/ysearch/web/v1/$thequery+$site?appid=$apikey&amp;format=xml&amp;count=".$plimit;
	}else{
		$url = 'http://boss.yahooapis.com/ysearch/web/v1/'.$thequery.'?appid='.$apikey.'&amp;format=xml&amp;count='.$plimit;
	}
	if (!empty($start)) $url .= "&amp;start=$start";
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	$data = curl_exec($ch);
	curl_close($ch);
	$results = new SimpleXmlElement($data, LIBXML_NOCDATA);
	$total = $results-&gt;resultset_web-&gt;attributes();
	$total = $total['totalhits'];
	$results = $results-&gt;resultset_web-&gt;result;
	$i = 0;
	$adyet = 1;
?&gt;
	&lt;div&gt;&lt;?=$total?&gt; results for &lt;b&gt;&lt;?=$_REQUEST['Keywords']?&gt;&lt;/b&gt;&lt;/div&gt;
&lt;?php
	foreach ($results as $theresult) {
		if( !empty($theresult-&gt;title) ){
			$string  = '&lt;div&gt;';
			$string .= '&lt;h2&gt;&lt;a href='.$theresult-&gt;clickurl.'&gt;'.$theresult-&gt;title.'&lt;/a&gt;&lt;/h2&gt;';
			$string .= '&lt;p&gt;'.$theresult-&gt;abstract.'&lt;/p&gt;';
			$string .= '&lt;a class="url" href='.$theresult-&gt;clickurl.'&gt;'.$theresult-&gt;dispurl.'&lt;/a&gt;';
			$string .= '&lt;br style="clear: both" /&gt;';
			$string .= '&lt;/div&gt;';
			echo $string;
			if($i == 3){
				echo '&lt;br style="clear: both" /&gt;';
				$i = 0;
			}
		}
	}
?&gt;
	&lt;br style="clear: both" /&gt;
	&lt;div id="pager"&gt;
&lt;?php
	if ($start &gt; 0){
		if ($start == $plimit)
			$startParam = '';
		else
			$startParam = "&amp;start=" . ($start - $plimit);
		echo dalink('Prev', $self . "?Keywords=$thequery" . $startParam) . "     ";
	}
	$page = 0;
	for ($i=0; $i&lt;$total; $i=$i+$plimit) {
		$page++;
		if ($i &gt; ($start-50) &amp;&amp; $i &lt; ($start+50)) {
			if ($i == $start) {
				echo " $page ";
			} else if ($i === 0) {
				echo dalink($page, $self . "?Keywords=$thequery");
			} else {
				echo dalink($page, $self . "?Keywords=$thequery&amp;start=$i");
			}
		} else if ($i == ($start-60)) {
			echo '... ';
		} else if ($i == ($start+60)) {
			echo '... '; break;
		}
	}
	echo "     ";
	if (count( $results ) === $plimit){
		$next = $start + $plimit;
		echo dalink('Next', $self . "?Keywords={$thequery}&amp;start={$next}");
	}
	$countPages = ceil($total / $plimit);
	echo "     ($total results on $countPages pages)";
?&gt;
	&lt;/div&gt;
&lt;?php
}
function dalink($text,$url){return "&lt;a href='{$url}'&gt;{$text}&lt;/a&gt;  ";}
?&gt;</code></pre>
<p>And that&#8217;s it, you now have your very own Yahoo BOSS powered search engine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/build-search-engine-boss/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build a dynamic menu in PHP</title>
		<link>http://www.thedevscene.com/tutorials/build-a-dynamic-menu-in-php</link>
		<comments>http://www.thedevscene.com/tutorials/build-a-dynamic-menu-in-php#comments</comments>
		<pubDate>Sun, 21 Sep 2008 11:49:32 +0000</pubDate>
		<dc:creator>Guest User</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[horror solutions]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=844</guid>
		<description><![CDATA[Not so long ago I was in a big search for a solution like this and my search didn&#8217;t lead to any positive results. I was looking for a dynamic PHP menu that will allow me to play with lots of options and situations. My application required some special code because it&#8217;s based on member [...]]]></description>
			<content:encoded><![CDATA[<p>Not so long ago I was in a big search for a solution like this and my search didn&#8217;t lead to any positive results. I was looking for a dynamic PHP menu that will allow me to play with lots of options and situations. My application required some special code because it&#8217;s based on member groups and so, my menu was supposed to reflect the permissions attached to each group in part. I was left with some horror solutions and this one explained in this article. Why horror? Well, imagine building a special menu for each group in part. Worst, my software will be sold to people, what if they create 100 groups with various combinations&#8230;what&#8217;s the menu now huh?! The following tutorial is based on my finished work which I&#8217;m very pleased with. I&#8217;m not just going to paste the code and explain but I will start with a basic example and going up the road of &#8220;dynamic&#8221;. Let&#8217;s imagine a menu array:</p>
<pre><code>
&lt;?php
	$menu = array (
		1 =&gt; 	array (
			'text'		=&gt; 	'Manage articles',
			'link'		=&gt; 	'#'
		),
		2 =&gt;	array(
			'text'		=&gt; 	'Manage articles',
			'link'		=&gt; 	'#'
		),
		3 =&gt;	array(
			'text'		=&gt; 	'Manage articles',
			'link'		=&gt; 	'#'
		),
		4 =&gt;	array(
			'text'		=&gt; 	'Manage articles',
			'link'		=&gt; 	'#'
		)
	);
?&gt;
</code></pre>
<p>It&#8217;s not that hard to imagine how would this example look in our browsers after writing some small lines of code to output it:</p>
<pre><code>
&lt;?php
	echo "&lt;ul id=navmenu-h&gt;";
	for ( $i = 1; $i &lt;= count ( $menu ); $i++ ){
		if ( is_array ( $menu [ $i ] ) ) {
?&gt;
			&lt;li class="&lt;?=$menu [ $i ] [ 'class' ]?&gt;"&gt;
				&lt;a  href="&lt;?=$menu [ $i ] [ 'link' ]?&gt;"&gt;&lt;?=$menu [ $i ] [ 'text' ];?&gt;&lt;/a&gt;
			&lt;/li&gt;
&lt;?
		}else {
			die ( sprintf ( 'menu nr %s must be an array', $i ) );
		}
	}
	echo "&lt;/ul&gt;";
?&gt;
</code></pre>
<p>The above code will create an unordered list with 4 elements. Simple and very basic I would say. At this point, our first question arrives: &#8220;How do we display each element based on permissions?&#8221;. For example, I want my 4th element to be shown only to users that are also customers. Tricky enough but still very easy. Let&#8217;s add another field to our arrays. One that will hold the condition which has to return boolean (TRUE/FALSE) in order for our application to decide if the element can be shown or not. Here&#8217;s how will our menu elements look after &#8220;upgrading&#8221; them to support this new feature that we need:</p>
<pre><code>
&lt;?php
	1 =&gt; 	array(
		'text'		=&gt; 	'Manage articles',
		'link'		=&gt; 	'#',
		'show_condition'=&gt;	is_customer (),
	)
?&gt;
</code></pre>
<p>The &#8220;show_condition&#8221; field will be our new field. You may notice the function &#8220;is_customer ()&#8221; which needs to return TRUE or FALSE. Any function or condition can be used, just follow your needs. This change will also be reflected in the code that is supposed to display the menu. Before outputting each menu element, our code will have to check if the &#8220;show_condition&#8221; is set to TRUE, otherwise keep it hidden:</p>
<pre><code>
&lt;?php
	if ( is_array ( $menu [ $i ] ) ) {
		if ( $menu [ $i ] [ 'show_condition' ] ) {//are we allowed to see this menu?
?&gt;
			&lt;li class="&lt;?=$menu [ $i ] [ 'class' ]?&gt;"&gt;
				&lt;a  href="&lt;?=$menu [ $i ] [ 'link' ]?&gt;"&gt;&lt;?=$menu [ $i ] [ 'text' ];?&gt;&lt;/a&gt;
			&lt;/li&gt;
&lt;?
		}
	}else {
		die ( sprintf ( 'menu nr %s must be an array', $key ) );
	}
?&gt;
</code></pre>
<p>Nice I would say. We&#8217;re starting to put a brain on our menu. It takes decisions. Let&#8217;s make it smarter! I want drop downs to group my elements and not fill my page and break my nice design with your menu. Ok, we&#8217;ll have to figure out a way to group them. Let&#8217;s try adding a new field into the arrays in order to specify parents. What&#8217;s a parent? Each menu that is a submenu will have in it&#8217;s declaration the key index of the main element that he&#8217;s a part of. The array now looks like this:</p>
<pre><code>
&lt;?php
	1 =&gt; 	array(
		'text'		=&gt; 	"Manage articles",
		'link'		=&gt; 	"#",
		'show_condition'=&gt;	is_customer (),
		'parent'	=&gt;	0
	)
?&gt;
</code></pre>
<p>In our example, the element is itself a parent because he links to no existing key index so this makes him a top level element. The array can be very flexible and every submenu can be a parent for another submenu and so on. There&#8217;s no limitation besides your CSS knowledge in order to make a menu that can also support multi-level drop downs. The example that I&#8217;ve attached at the bottom of this tutorial is based on one of the great examples from CSSplay (you can find hundreds of them there, very good examples) and supports 3 levels which should be enough to most of us. The next question that comes into our minds is how the heck to we display them? How do we put the parent on top of it&#8217;s childs and parent-childs on top of&#8230;.you know the rest. It&#8217;s not hard but kept me busy for a little while. A lot of &#8220;fun&#8221; with arrays and loops. The principle is simple in theory: we will make a function that displays the top elements (parent = 0) and inside every element we will insert another function that loops through childs until all categories and subcategories will find their end.</p>
<pre><code>
&lt;?php
	function build_menu ( $menu ){
		$out = "\n".'&lt;ul&gt;' . "\n";
		for ( $i = 1; $i &lt;= count ( $menu ); $i++ )
		{
			if ( is_array ( $menu [ $i ] ) ) {//must be by construction but let's keep the errors home
				if ( $menu [ $i ] [ 'show_condition' ] &amp;&amp; $menu [ $i ] [ 'parent' ] == 0 ) {//are we allowed to see this menu?
					$out .= '&lt;li&gt;&lt;a href="' . $menu [ $i ] [ 'link' ] . '"&gt;';
					$out .= $menu [ $i ] [ 'text' ];
					$out .= '&lt;/a&gt;';
					$out .= get_childs ( $menu, $i );//loop through childs
					$out .= '&lt;/li&gt;' . "\n";
				}
			}
			else {
				die ( sprintf ( 'menu nr %s must be an array', $i ) );
			}
		}
		$out .= '&lt;/ul&gt;'."\n";
		return $out;
	}
?&gt;
</code></pre>
<p>The above function picks the top elements exactly how we needed ( $menu [ $i ] [ 'parent' ] == 0 ) and also allows our second function to loop through the childs of every top menu ( get_childs ( $menu, $i ) ). This is just basic stuff, no complicated things, 2 parameters that need to be met (show_condition must be true otherwise we&#8217;re not allowed to view this menu and parent must be 0 because we want only top elements in this loop ), and the top elements are displayed. More interesting is how we build the 2nd function that will have to go down the category tree until no child of parent is left orphan. The skeleton is somewhat the same. The 2nd function will loop through the array and, foreach element that has in it&#8217;s parent the id that is passed it grabs it and loops again through the new id until it&#8217;s finished. Simpler, the function calls itself passing by the parents:</p>
<pre><code>
&lt;?php
	function get_childs ( $menu, $el_id )
	{
		$has_subcats = FALSE;
		$out = '';
		$out .= "\n".'	&lt;ul&gt;' . "\n";
		for ( $i = 1; $i &lt;= count ( $menu ); $i++ ){
			if ( $menu [ $i ] [ 'show_condition' ] &amp;&amp; $menu [ $i ] [ 'parent' ] == $el_id ) {//are we allowed to see this menu?
				$has_subcats = TRUE;
				$out .= "&lt;li&gt;&lt;a href='{$menu[ $i ][ 'link' ]}}'&gt;{$menu [ $i ] [ 'text' ]}&lt;/a&gt;".get_childs ( $menu, $i )"&lt;/li&gt;";
			}
		}
		$out .= '	&lt;/ul&gt;'."\n";
		return ( $has_subcats ) ? $out : FALSE;
	}
?&gt;
</code></pre>
<p>This example that we learned can also work with databases. Just set up the table with the array fields ( text, link etc&#8230; ) and you&#8217;re good to go. The array can be extended hugely. Classes can be passed, images, hoover effects, targets&#8230;many, many options and many levels can be added. Our handy functions will find and show them all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/build-a-dynamic-menu-in-php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Shell Script To Auto Restart Apache HTTPD When it Goes Down / Dead</title>
		<link>http://www.thedevscene.com/tutorials/shell-script-to-auto-restart-apache-httpd-when-it-goes-down-dead</link>
		<comments>http://www.thedevscene.com/tutorials/shell-script-to-auto-restart-apache-httpd-when-it-goes-down-dead#comments</comments>
		<pubDate>Fri, 19 Sep 2008 18:25:07 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[operating system]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[Web Server When It Goes Down]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=789</guid>
		<description><![CDATA[Here is a simple shell script tested on CentOS / RHEL / Fedora / Debian / Ubuntu Linux. Should work under any other UNIX liker operating system. It will check for httpd pid using pgrep command pgrep command pgrep looks through the currently running processes and lists the process IDs which matches the selection criteria [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a simple shell script tested on CentOS / RHEL / Fedora / Debian / Ubuntu Linux. Should work under any other UNIX liker operating system. It will check for httpd pid using pgrep command<br />
pgrep command</p>
<p>pgrep looks through the currently running processes and lists the process IDs which matches the selection criteria to screen. If no process found it will simply return exit status 0 (zero).</p>
<p>Download the script and set cronjob as follows:</p>
<pre><code>*/5 * * * * /path/to/script.sh &gt;/dev/null 2&gt;&amp;1</code></pre>
<p>Sample script</p>
<pre><code>#!/bin/bash
# Apache Process Monitor
# Restart Apache Web Server When It Goes Down
# -------------------------------------------------------------------------
# RHEL / CentOS / Fedora Linux restart command
RESTART="/sbin/service httpd restart"

# uncomment if you are using Debian / Ubuntu Linux
#RESTART="/etc/init.d/apache2 restart"

#path to pgrep command
PGREP="/usr/bin/pgrep"

# Httpd daemon name,
# Under RHEL/CentOS/Fedora it is httpd
# Under Debian 4.x it is apache2
HTTPD="httpd"

# find httpd pid
$PGREP ${HTTPD}

if [ $? -ne 0 ] # if apache not running
then
 # restart apache
 $RESTART
fi</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/shell-script-to-auto-restart-apache-httpd-when-it-goes-down-dead/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Track visitors with PHP</title>
		<link>http://www.thedevscene.com/tutorials/track-visitors-php</link>
		<comments>http://www.thedevscene.com/tutorials/track-visitors-php#comments</comments>
		<pubDate>Sat, 27 Oct 2007 00:28:20 +0000</pubDate>
		<dc:creator>Guest User</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[$protocol]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[people search]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[return $protocol]]></category>
		<category><![CDATA[rigger]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com/?p=1693</guid>
		<description><![CDATA[When it comes to websites, a very important item is having the ability to track your website&#8217;s visitors. Analyzing your traffic and optimizing your pages is the best way to get the most of your visitors. There are many reasons why you should think of implementing tracking scripts (it&#8217;s crucial to know where your traffic [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to websites, a very important item is having the ability to track your website&#8217;s visitors. Analyzing your traffic and optimizing your pages is the best way to get the most of your visitors. There are many reasons why you should think of implementing tracking scripts (it&#8217;s crucial to know where your traffic is coming from and where it goes, what people search, how long they stay etc.), you could increase sales, you could optimize your pages to increase page hits, you could make lots of changes to increase your Adsense profits and the list goes on and on. You name it.</p>
<p>In this tutorial we will create a MySql based tracking script written in PHP which will do a simple task &#8211; store each visitor that browsed our page with IP, hours, dates, browser types, reffering url and visited page. We will start by creating a database that will be used by our php script to store the required data. Let&#8217;s call it &#8220;visitor_tracker&#8221;. Now that our database is created all we need at this moment is a table that will store our data. We will call it &#8220;visitors_table&#8221;. Our table will have 9 rows as following:</p>
<pre name="code" class="sql">CREATE TABLE `visitors_table` (
`ID` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`visitor_ip` VARCHAR( 32 ) NULL ,
`visitor_browser` VARCHAR( 255 ) NULL ,
`visitor_hour` SMALLINT( 2 ) NOT NULL DEFAULT '00',
`visitor_minute` SMALLINT( 2 ) NOT NULL DEFAULT '00',
`visitor_date` TIMESTAMP( 32 ) NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`visitor_day` SMALLINT( 2 ) NOT NULL ,
`visitor_month` SMALLINT( 2 ) NOT NULL ,
`visitor_year` SMALLINT( 4 ) NOT NULL ,
`visitor_refferer` VARCHAR( 255 ) NULL ,
`visitor_page` VARCHAR( 255 ) NULL
) TYPE = MYISAM ;</code></pre>
<p>&#8230;we&#8217;ve set some values to &#8220;NOT NULL&#8221; so that our server can continue it&#8217;s job and still store a record if some values are missing (the most comon reason for a detail to be missed is a bad detection script used). Ok. We have our database ready for storing our visitors info so what&#8217;s next? We will need to setup a script which will store the visitor&#8217;s info in our database so let&#8217;s start writing it. We need the ip address of our visitor so we will get it using the following method.</p>
<pre><code>
&lt;?php
$visitor_ip = GetHostByName($REMOTE_ADDR);?&gt;
</code></pre>
<p>&#8230;next we need the browser type of our visitor and we will use this function to get it:</p>
<pre><code>
&lt;?php
function getBrowserType () {
if (!empty($_SERVER['HTTP_USER_AGENT']))
{
   $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
}
else if (!empty($HTTP_SERVER_VARS['HTTP_USER_AGENT']))
{
   $HTTP_USER_AGENT = $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
}
else if (!isset($HTTP_USER_AGENT))
{
   $HTTP_USER_AGENT = '';
}
if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[2];
   $browser_agent = 'opera';
}
else if (ereg('MSIE ([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'ie';
}
else if (ereg('OmniWeb/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'omniweb';
}
else if (ereg('Netscape([0-9]{1})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'netscape';
}
else if (ereg('Mozilla/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'mozilla';
}
else if (ereg('Konqueror/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'konqueror';
}
else
{
   $browser_version = 0;
   $browser_agent = 'other';
}
return $browser_agent;
}
?&gt;
</code></pre>
<p>so there it is:</p>
<pre><code>
&lt;?php
$visitor_browser = getBrowserType();?&gt;
</code></pre>
<p>Now lets get the hour, minute, day, month and year of this visit:</p>
<pre><code>
&lt;?php
$visitor_hour = date("h");
$visitor_minute = date("i");
$visitor_day = date("d");
$visitor_month = date("m");
$visitor_year = date("y");
?&gt;
</code></pre>
<p>next we need to find out who is sending us visitors so we can thank them.</p>
<pre><code>
&lt;?php
$visitor_refferer = gethostbyname($HTTP_REFERER);
?&gt;
</code></pre>
<p>&#8230;to get the full url of our page we will use this function:</p>
<pre><code>
&lt;?php
function selfURL() {
$s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
$protocol = strleft(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $protocol."://".$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
}
function strleft($s1, $s2) { return substr($s1, 0, strpos($s1, $s2));
}
?&gt;
</code></pre>
<p>ok so we have our page, we will store it on a variable:</p>
<pre><code>
&lt;?php
$visited_page = selfURL();
?&gt;
</code></pre>
<p>We will create a new page which will be used to connect to the database and to store our functions. Let&#8217;s name it visitors_connections.php. we will paste this code and save it:</p>
<pre><code>
&lt;?php
$hostname_visitors = "host";
$database_visitors = "database";
$username_visitors = "username";
$password_visitors = "password";

$visitors = mysql_connect($hostname_visitors, $username_visitors,
 $password_visitors) or rigger_error(mysql_error(),E_USER_ERROR);

function getBrowserType () {
if (!empty($_SERVER['HTTP_USER_AGENT']))
{
   $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
}
else if (!empty($HTTP_SERVER_VARS['HTTP_USER_AGENT']))
{
   $HTTP_USER_AGENT = $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
}
else if (!isset($HTTP_USER_AGENT))
{
   $HTTP_USER_AGENT = '';
}
if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[2];
   $browser_agent = 'opera';
}
else if (ereg('MSIE ([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'ie';
}
else if (ereg('OmniWeb/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'omniweb';
}
else if (ereg('Netscape([0-9]{1})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'netscape';
}
else if (ereg('Mozilla/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'mozilla';
}
else if (ereg('Konqueror/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version))
{
   $browser_version = $log_version[1];
   $browser_agent = 'konqueror';
}
else
{
   $browser_version = 0;
   $browser_agent = 'other';
}
return $browser_agent;
}

function selfURL() {
$s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
$protocol = strleft(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $protocol."://".$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
}

function strleft($s1, $s2) { return substr($s1, 0, strpos($s1, $s2)); }

function paginate($start,$limit,$total,$filePath,$otherParams) {
	global $lang;

	$allPages = ceil($total/$limit);

	$currentPage = floor($start/$limit) + 1;

	$pagination = "";
	if ($allPages&gt;10) {
		$maxPages = ($allPages&gt;9) ? 9 : $allPages;

		if ($allPages&gt;9) {
			if ($currentPage&gt;=1&amp;&amp;$currentPage&lt;=$allPages) {
				$pagination .= ($currentPage&gt;4) ? " ... " : " ";

				$minPages = ($currentPage&gt;4) ? $currentPage : 5;
				$maxPages = ($currentPage&lt;$allPages-4) ? $currentPage : $allPages - 4;

				for($i=$minPages-4; $i&lt;$maxPages+5; $i++) {
					$pagination .= ($i == $currentPage) ? "&lt;a href=\"#\"
					class=\"current\"&gt;".$i."&lt;/a&gt; " : "&lt;a href=\"".$filePath."?
					start=".(($i-1)*$limit).$otherParams."\"&gt;".$i."&lt;/a&gt; ";
				}
				$pagination .= ($currentPage&lt;$allPages-4) ? " ... " : " ";
			} else {
				$pagination .= " ... ";
			}
		}
	} else {
		for($i=1; $i&lt;$allPages+1; $i++) {
		$pagination .= ($i==$currentPage) ? "&lt;a href=\"#\" class=\"current\"&gt;".$i."&lt;/a&gt; "
		: "&lt;a href=\"".$filePath."?start=".(($i-1)*$limit).$otherParams."\"&gt;".$i."&lt;/a&gt; ";
		}
	}

	if ($currentPage&gt;1) $pagination = "&lt;a href=\"".$filePath."?
	start=0".$otherParams."\"&gt;FIRST&lt;/a&gt; &lt;a href=\"".$filePath."?
	start=".(($currentPage-2)*$limit).$otherParams."\"&gt;&lt;&lt;/a&gt; ".$pagination;
	if ($currentPage&lt;$allPages) $pagination .= "&lt;a href=\"".$filePath."?
	start=".($currentPage*$limit).$otherParams."\"&gt;&gt;&lt;/a&gt; &lt;a href=\"".$filePath."?
	start=".(($allPages-1)*$limit).$otherParams."\"&gt;LAST&lt;/a&gt;";

	echo '&lt;div class="pages"&gt;' . $pagination . '&lt;/div&gt;';
}
?&gt;
</code></pre>
<p>Ok&#8230;we have all the details stored in variables so we need to write them into our database. We will create a new file called &#8220;visitor_tracking.php&#8221; and include it in every page that we want to track:</p>
<pre><code>
&lt;?php
require_once('visitors_connections.php');//the file with connection code and functions
//get the required data

$visitor_ip = GetHostByName($REMOTE_ADDR);
$visitor_browser = getBrowserType();
$visitor_hour = date("h");
$visitor_minute = date("i");
$visitor_day = date("d");
$visitor_month = date("m");
$visitor_year = date("Y");
$visitor_refferer = GetHostByName($HTTP_REFERER);
$visited_page = selfURL();

//write the required data to database
mysql_select_db($database_visitors, $visitors);
$sql = "INSERT INTO visitors_table (visitor_ip, visitor_browser, visitor_hour,
 visitor_minute, visitor_date, visitor_day, visitor_month, visitor_year,
 visitor_refferer, visitor_page) VALUES ('$visitor_ip', '$visitor_browser',
 '$visitor_hour', '$visitor_minute', '$visitor_date', '$visitor_day', '$visitor_month',
 '$visitor_year', '$visitor_refferer', '$visitor_page')";
$result = mysql_query($sql) or trigger_error(mysql_error(),E_USER_ERROR);
?&gt;
</code></pre>
<p>We have everything we need except for a page to display our data. We will start by creating a new page called display_visits.php where we paste the following code:</p>
<pre><code>
&lt;?php
require_once('visitors_connections.php');//the file with connection code and functions

if ($_GET['start'] == "") $start = 0;
else $start = $_GET['start'];
$limit = 15;

$additionalQuery = "SQL_CALC_FOUND_ROWS ";

mysql_select_db($database_visitors, $visitors);
$query_visitors = "(SELECT ".$additionalQuery." * FROM visitors_table WHERE";

if ($_POST['day']!="") {
$query_visitors .= " visitor_day = '".$_POST['day']."'";
} else {
$query_visitors .= " visitor_day = ".date("d")."";

if ($_POST['month']!="") {
$query_visitors .= " AND visitor_month = '".$_POST['month']."'";
} else {
$query_visitors .= " AND visitor_month = ".date("m")."";
}

if ($_POST['year']!="") {
$query_visitors .= " AND visitor_year = '".$_POST['year']."'";
} else {
$query_visitors .= " AND visitor_year = ".date("Y")."";
}}
$query_visitors .= " LIMIT $start,$limit)";
$insert_visitors = mysql_query($query_visitors, $visitors) or die(mysql_error());
$row_visitors = mysql_fetch_assoc($insert_visitors);
$totalRows_visitors = mysql_num_rows($insert_visitors);

$nbItems = mysql_result(mysql_query("Select FOUND_ROWS() AS nbr"),0,"nbr");
if ($nbItems&gt;($start+$limit)) $final = $start+$limit;
else $final = $nbItems;

echo '&lt;table style="width:100%; border:1px dashed #CCC" cellpadding="3"&gt;
      &lt;form id="form1" name="form1" method="post" action="display_visits.php"&gt;
       &lt;tr&gt;
        &lt;td&gt;day
        &lt;select name="day" id="day"&gt;
          &lt;option value="" selected="selected"&gt;&lt;/option&gt;
          &lt;option value="01"&gt;01&lt;/option&gt;
          &lt;option value="02"&gt;02&lt;/option&gt;
          &lt;option value="03"&gt;03&lt;/option&gt;
          &lt;option value="04"&gt;04&lt;/option&gt;
          &lt;option value="05"&gt;05&lt;/option&gt;
          &lt;option value="06"&gt;06&lt;/option&gt;
          &lt;option value="07"&gt;07&lt;/option&gt;
          &lt;option value="08"&gt;08&lt;/option&gt;
          &lt;option value="09"&gt;09&lt;/option&gt;
          &lt;option value="10"&gt;10&lt;/option&gt;
          &lt;option value="11"&gt;11&lt;/option&gt;
          &lt;option value="12"&gt;12&lt;/option&gt;
          &lt;option value="13"&gt;13&lt;/option&gt;
          &lt;option value="14"&gt;14&lt;/option&gt;
          &lt;option value="15"&gt;15&lt;/option&gt;
          &lt;option value="16"&gt;16&lt;/option&gt;
          &lt;option value="17"&gt;17&lt;/option&gt;
          &lt;option value="18"&gt;18&lt;/option&gt;
          &lt;option value="19"&gt;19&lt;/option&gt;
          &lt;option value="20"&gt;20&lt;/option&gt;
          &lt;option value="21"&gt;21&lt;/option&gt;
          &lt;option value="22"&gt;22&lt;/option&gt;
          &lt;option value="23"&gt;23&lt;/option&gt;
          &lt;option value="24"&gt;24&lt;/option&gt;
          &lt;option value="25"&gt;25&lt;/option&gt;
          &lt;option value="26"&gt;26&lt;/option&gt;
          &lt;option value="27"&gt;27&lt;/option&gt;
          &lt;option value="28"&gt;28&lt;/option&gt;
          &lt;option value="29"&gt;29&lt;/option&gt;
          &lt;option value="30"&gt;30&lt;/option&gt;
          &lt;option value="31"&gt;31&lt;/option&gt;
        &lt;/select&gt;&lt;/td&gt;
        &lt;td&gt;Month
        &lt;select name="month" id="month"&gt;
          &lt;option value="" selected="selected"&gt;&lt;/option&gt;
          &lt;option value="1"&gt;1&lt;/option&gt;
          &lt;option value="2"&gt;2&lt;/option&gt;
          &lt;option value="3"&gt;3&lt;/option&gt;
          &lt;option value="4"&gt;4&lt;/option&gt;
          &lt;option value="5"&gt;5&lt;/option&gt;
          &lt;option value="6"&gt;6&lt;/option&gt;
          &lt;option value="7"&gt;7&lt;/option&gt;
          &lt;option value="8"&gt;8&lt;/option&gt;
          &lt;option value="9"&gt;9&lt;/option&gt;
          &lt;option value="10"&gt;10&lt;/option&gt;
          &lt;option value="11"&gt;11&lt;/option&gt;
          &lt;option value="12"&gt;12&lt;/option&gt;
        &lt;/select&gt;&lt;/td&gt;
        &lt;td&gt;Year
        &lt;select name="year" id="year"&gt;
          &lt;option value="" selected="selected"&gt;&lt;/option&gt;
          &lt;option value="2007"&gt;2007&lt;/option&gt;
        &lt;/select&gt;&lt;/td&gt;
        &lt;td&gt;&lt;input type="submit" name="Submit" value="Submit" /&gt;&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
       &lt;/tr&gt;';

echo '&lt;tr&gt;
        &lt;td style="width:15%;border-bottom:1px solid #CCC"&gt;IP&lt;/td&gt;
        &lt;td style="width:15%;border-bottom:1px solid #CCC"&gt;Browser&lt;/td&gt;
        &lt;td style="width:15%;border-bottom:1px solid #CCC"&gt;Time&lt;/td&gt;
        &lt;td style="width:30%;border-bottom:1px solid #CCC"&gt;Refferer&lt;/td&gt;
        &lt;td style="width:25%;border-bottom:1px solid #CCC"&gt;Page&lt;/td&gt;
       &lt;/tr&gt;';

do {

echo '&lt;tr onmouseout="this.style.backgroundColor=\'\'"
      onmouseover="this.style.backgroundColor=\'#EAFFEA\'"&gt;
        &lt;td&gt;'.$row_visitors['visitor_ip'].'&lt;/td&gt;
        &lt;td&gt;'.$row_visitors['visitor_browser'].'&lt;/td&gt;
        &lt;td&gt;'.$row_visitors['visitor_hour'].':'.$row_visitors['visitor_minute'].'&lt;/td&gt;
        &lt;td&gt;'.$row_visitors['visitor_refferer'].'&lt;/td&gt;
        &lt;td&gt;'.$row_visitors['visitor_page'].'&lt;/td&gt;
       &lt;/tr&gt;';
} while ($row_visitors = mysql_fetch_assoc($insert_visitors));
paginate($start,$limit,$nbItems,"display_visits.php","");
?&gt;
</code></pre>
<p>There&#8217;s only one small step to do and we&#8217;re ready to see some results. We need to include the following line in every page that we need to track results for:</p>
<pre><code>
&lt;?php
include('visitor_tracking.php');
?&gt;
</code></pre>
<p>To see the results please navigate to &#8220;display_visits.php&#8221; in your browser and start to benefit from tracking your visitors. Ok now I&#8217;m testing it, it works fine, I hope you will find it useful somewhere in your website. In our next tutorials we will get a little bit more complicated and add some charts maybe or some calculations to show us some more informations like hits vs uniques, how many returning visitors etc.</p>
<div align=center>
<a href="http://www.thedevscene.com/wp-content/uploads/2008/11/counter.zip">Click here to download the files for this article</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/track-visitors-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SitePoint.com: Build a Photo Gallery Using CakePHP and Flickr</title>
		<link>http://www.thedevscene.com/tutorials/sitepointcom-build-a-photo-gallery-using-cakephp-and-flickr</link>
		<comments>http://www.thedevscene.com/tutorials/sitepointcom-build-a-photo-gallery-using-cakephp-and-flickr#comments</comments>
		<pubDate>Thu, 12 Apr 2007 07:00:00 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[web gallery]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com//tutorials/php/sitepointcom-build-a-photo-gallery-using-cakephp-and-flickr/</guid>
		<description><![CDATA[Want to share your Flickr photostream with the world, but only once you&#8217;ve given it a nice, customized touch? Look no further than CakePHP &#8212; and a few lines of code &#8212; to pull off some magic! In this article, we&#8217;ll use the Flickr API and CakePHP to take the images we&#8217;ve loaded onto Flickr [...]]]></description>
			<content:encoded><![CDATA[<p>Want to share your Flickr photostream with the world, but only once you&#8217;ve given it a nice, customized touch? Look no further than CakePHP &#8212; and a few lines of code &#8212; to pull off some magic! In this article, we&#8217;ll use the Flickr API and CakePHP to take the images we&#8217;ve loaded onto Flickr and use them to build our own, non-Flickr web gallery.<a href="http://www.sitepoint.com/article/photo-gallery-cakephp-flickr" rel="nofollow" target="_new">[Read More]</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/sitepointcom-build-a-photo-gallery-using-cakephp-and-flickr/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Bakery: How I Built a Web 2.0 Dating Site in 66.5 Hours</title>
		<link>http://www.thedevscene.com/tutorials/the-bakery-how-i-built-a-web-20-dating-site-in-665-hours</link>
		<comments>http://www.thedevscene.com/tutorials/the-bakery-how-i-built-a-web-20-dating-site-in-665-hours#comments</comments>
		<pubDate>Fri, 30 Mar 2007 07:00:00 +0000</pubDate>
		<dc:creator>Roger Stringer</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[free online dating website]]></category>
		<category><![CDATA[prominent real estate]]></category>

		<guid isPermaLink="false">http://www.quickpipe.com//tutorials/php/the-bakery-how-i-built-a-web-20-dating-site-in-665-hours/</guid>
		<description><![CDATA[On the Bakery (the CakePHP blog), there&#8217;s a new case study on how a group of developers created a &#8220;Web 2.0 dating site in 66.5 hours&#8221; (just short of 3 days worth of work). &#8220;Let this be a testament to Web 2.0 and the effectiveness of rapid development frameworks: I built a full-featured dating website [...]]]></description>
			<content:encoded><![CDATA[<p>On the Bakery (the CakePHP blog), there&#8217;s a new case study on how a group of developers created a &#8220;Web 2.0 dating site in 66.5 hours&#8221; (just short of 3 days worth of work).</p>
<p>&#8220;Let this be a testament to Web 2.0 and the effectiveness of rapid development frameworks: I built a full-featured dating website (http://mingle2.com), from concept to launch, in 66.5 hours. In a typical<br />
9-5 job this would amount to about a week and a half. Deliverables included: the idea, planning, design, development, testing, and launch. &#8221;</p>
<p>The study is broken up into the (long list of) key steps that were followed:
<ul>
<li>Identify an Opportunity
<li>Brain-dump
<li>Generate ideas from your competition
<li>Brain-dump some more
<li>Have a specific goal, don&#8217;t try to make the website do everything
<li>Keep. It. Simple. Stupid
<li>Minimize interference
<li>Avoid &#8220;feature creep&#8221;
<li>Web 2.0 names are going to be very tacky in a few years
<li>If you get stuck on something, put it on the backburner
<li>Prioritize features so you can give prominent real estate to those that need it
<li>Put a lot of work into the functional mockups
<li>Mix it up, keep things interesting
</ul>
<p>And finally, &#8220;The Design&#8221; where he looked at achieving balance, got a &#8220;holy crap, that&#8217;s pretty&#8221; reaction, and to make things look up to date. The end result of the labor is mingle2.com, a 100% free online dating website.<a href="http://bakery.cakephp.org/articles/view/309" rel="nofollow" target="_new">[Read More]</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedevscene.com/tutorials/the-bakery-how-i-built-a-web-20-dating-site-in-665-hours/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->