<?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>Query7 &#187; php</title>
	<atom:link href="http://query7.com/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://query7.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 09 Apr 2010 09:36:13 +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>Writing an Event System in PHP</title>
		<link>http://query7.com/writing-an-event-system-in-php</link>
		<comments>http://query7.com/writing-an-event-system-in-php#comments</comments>
		<pubDate>Sat, 06 Mar 2010 00:31:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=596</guid>
		<description><![CDATA[<p>In this tutorial you will learn how to create and implement an event system in PHP. You will be able to integrate it with your own web application or framework.</p>
<h3>What is an event system?</h3>
<p>An event system is a&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial you will learn how to create and implement an event system in PHP. You will be able to integrate it with your own web application or framework.</p>
<h3>What is an event system?</h3>
<p>An event system is a way to call prefined functions at a specified time in your application code. It&#8217;s main use is to allow developers to add functionality to your code without modifying the original source. Directly editing the source code of an application is proven not to work because every time the software gets updated, the changes made to the source get overwritten. By offering an event system in your application developers will be able to write plugin style code which will get executed at a specified time in the main application code. This makes your platform easier to develop for and offers a low entry level for coders wanting to add functionality themselves.</p>
<h3>Overview of the system</h3>
<p><em>event::$events</em> is a static variable (array) which holds all of the registered events and associated Closure objects.</p>
<p><em>event::register(&#8216;eventName&#8217;, function($args){})</em> accepts two arguments. The first being the name of the event and the second being a Closure object which will be called when the event is fired. You can see we use type hinting for the second argument to only accept a Closure object, this way we don&#8217;t need to write extra code in the function to check whether the method is callable.</p>
<pre>
    public static function register($event, Closure $func)
    {
        self::$events[$event][] = $func;
    }
</pre>
<p><em>event::fire(&#8216;eventName&#8217;, $args)</em> also accepts two arguments. The first is the event name and the second is an array of arguments that will be passed to the Closure function when it is called. Because we can register multiple methods to one event, we need to iterate over the array of events and then call the function with passed arguments.</p>
<pre>
    public static function fire($event, $args = array())
    {
        if(isset(self::$events[$event]))
        {
            foreach(self::$events[$event] as $func)
            {
                call_user_func($func, $args);
            }
        }

    }
</pre>
<h3>Usage</h3>
<p>Suppose we were writing a blogging platform and we wanted to make it easy for developers to call functions when a new blog post was created or deleted. In the appropriate location we would call the fire event::method(). In this case we are passing $postInfo , an array of post data, as an argument</p>
<pre>event::fire('blog.post.create', $postInfo);</pre>
<p>If we wanted to send an email to someone every time a post is published we only need to register an event and include the code.</p>
<pre>
event::register('blog.post.create', function($args = array()){

    mail('myself@me.com', 'Blog Post Published', $args['name'] . ' has been published');

});
</pre>
<p>Alternatively, if the event system were put to use in a framework, there could be events for various times during the framework&#8217;s loading process (eg. before routing, before calling the controller function, before accessing the database). We would call the fire function at these times.</p>
<pre>
event::fire('pre.controller');
</pre>
<pre>
event::register('pre.controller', function($args = array()){

	log::write('pre controller');

	//include some relevant files
});
</pre>
<h3>Full source</h3>
<pre>
class event
{

    public static $events = array();

    public static function fire($event, $args = array())
    {
        if(isset(self::$events[$event]))
        {
            foreach(self::$events[$event] as $func)
            {
                call_user_func($func, $args);
            }
        }

    }

    public static function register($event, Closure $func)
    {
        self::$events[$event][] = $func;
    }

}
</pre>
<p>If you have any questions or comments about the event class please ask below in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/writing-an-event-system-in-php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Preventing CSRF in PHP</title>
		<link>http://query7.com/preventing-csrf-in-php</link>
		<comments>http://query7.com/preventing-csrf-in-php#comments</comments>
		<pubDate>Tue, 16 Feb 2010 22:21:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=587</guid>
		<description><![CDATA[<p>Cross site request forgery (CSRF) is where a malicious website will attempt to issue actions on another website without the user&#8217;s knowledge of it occuring.</p>
<p>Hypothetical Situation: You had just done some online banking and had ticked the &#8216;Remember me&#8217;&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Cross site request forgery (CSRF) is where a malicious website will attempt to issue actions on another website without the user&#8217;s knowledge of it occuring.</p>
<p>Hypothetical Situation: You had just done some online banking and had ticked the &#8216;Remember me&#8217; option when you logged in. The banking website easily allows you to transfer money to other people. While browsing the malicious site you see a link that seems to take you somewhere harmless but it actually sends you to www.my.bank/transfer?to=3740384342?amount=99999 . Because you ticked &#8216;remember me&#8217; you are automatically logged in and the bank goes ahead and transfers the funds.</p>
<p>There are some obvious fundamental issues the bank could address such as checking with the user whether they want to send the funds and masking their URLs but the problem of the form still remains. Theres nothing from stopping anyone sending seemingly valid data to the URL the form submits to. This problem is known as Cross Site Request Forgery (CSRF) and it is a potential problem in every single dynamic website. While stealing money is an extreme example, CSRF could also be used to steal cookies from a website or post spammy comments on a blog without the user being aware that they are doing so.</p>
<p>Actions on websites are always associated with forms &#8211; logging in, transferring funds or posting a comment on the blog. Our solution to the CSRF problem is to generate a unique key when the user visits the page with the form on it. We set this key as a <em>$_SESSION</em> as well as a hidden input field in the form.  When the form is submitted we will check the key stored in the session and the key posted by the form. If they are the same then we know the user willingly submitted the form. If they don&#8217;t match (or the <em>$_SESSION</em> key is empty) then we know something malicious is going on and we can safely redirect the user (and take no action).</p>
<pre>
session_start();<br/><br/>//if the form was submitted..<br/>if(isset($_POST['submit']))<br/>{<br/><br/>    //check the tokens<br/>    if($_SESSION['csrfToken'] == $_POST['csrfToken'])<br/>    {<br/>        echo 'form is good';<br/>    }<br/>    else<br/>    {<br/>        header(&quot;Location: www.query7.com&quot;);<br/>    }<br/><br/>}<br/>else<br/>{<br/><br/>//generate the token<br/>$token = md5(uniqid(rand(), TRUE));<br/><br/>//set the token as a session<br/>$_SESSION['csrfToken'] = $token;<br/><br/><br/>//our form with the hidden field<br/>$form = '<br/>&lt;form method=&quot;POST&quot; action=&quot;&quot;&gt;<br/>Account: &lt;input type=&quot;text&quot; name=&quot;account&quot; /&gt;&lt;br /&gt;<br/>Amount: &lt;input type=&quot;text&quot; name=&quot;amount&quot; /&gt;&lt;br /&gt;<br/>&lt;input type=&quot;hidden&quot; name=&quot;csrfToken&quot; value=&quot;' . $token . '&quot; /&gt;<br/>&lt;input type=&quot;submit&quot; value=&quot;Send Money&quot; name=&quot;submit&quot; /&gt;<br/><br/>&lt;/form&gt;';<br/><br/>echo $form;<br/><br/><br/>}
</pre>
<p>We can add an additional level of security by making sure the user was fowarded from the page that contains the form.</p>
<pre>

//after checking of the tokens match

if(!$_SERVER['HTTP_REFERER'] == 'http://yoursite.com/location/of/form.php')
{

    header('Location: http://www.yoursite.com/tricked.php');
}
</pre>
<p>If you have any questions about CSRF or how to protect against it please ask them in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/preventing-csrf-in-php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP in Action &#8211; Objects, Design, Agility</title>
		<link>http://query7.com/php-in-action-objects-design-agility</link>
		<comments>http://query7.com/php-in-action-objects-design-agility#comments</comments>
		<pubDate>Sun, 31 Jan 2010 00:38:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=571</guid>
		<description><![CDATA[<p><strong><font size=5>Book Review</font><br /></strong><br />
<a href="http://query7.com/wp-content/uploads/2010/01/php-inaction.jpg"><img src="http://query7.com/wp-content/uploads/2010/01/php-inaction-300x300.jpg" alt="" title="php inaction" width="300" height="300" class="alignnone size-medium wp-image-573" /></a></p>
<p>
PHP in Action is a book aimed at people who are comfortable coding procedural or object orientated PHP scripts. It doesn&#8217;t teach you what a variable is or what function to use if you want&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p><strong><font size=5>Book Review</font><br /></strong><br />
<a href="http://query7.com/wp-content/uploads/2010/01/php-inaction.jpg"><img src="http://query7.com/wp-content/uploads/2010/01/php-inaction-300x300.jpg" alt="" title="php inaction" width="300" height="300" class="alignnone size-medium wp-image-573" /></a></p>
<p>
PHP in Action is a book aimed at people who are comfortable coding procedural or object orientated PHP scripts. It doesn&#8217;t teach you what a variable is or what function to use if you want to connect to a database but it does teach you design patterns, best practice techniques and useful information about PHP5&#8242;s object system. If you are looking into writing a PHP framework or want to further understand design patterns and objects in PHP then I highly recommend this book. It&#8217;s written by prominent members of the PHP community &#8211; Dagfinn Reiersol, Marcus Baker and Chris Shiflett and is 525 pages long.</p>
<p>
<font size=4>Overview of the book</font></p>
<p>
Chapters 2,3,4 cover the PHP5 class system. The book offers detailed and useful examples of each of the topics as well as plenty of metaphors to help the reader understand exactly what each feature should do and is capable of doing. I found this contrasted greatly with the almost minimal explanations and examples offered by the official documentation on php.net. The following features are covered:</p>
<ul>
<li>
    Magic Methods &#8211; __get(), __set(), __construct(), __autoload()
  </li>
<li>
    Exception handling
  </li>
<li>
    Error handling
  </li>
<li>
    Property visibility &#8211; public, protected, private
  </li>
<li>
    Abstract classes
  </li>
<li>
    Static methods
  </li>
<li>
    Interfaces
  </li>
</ul>
<p>
Chapters 5,6,7 talk about object orientated principles and design patterns. Object orientated patterns and solutions are discussed including the Open Closed Principle, Single Responsibility Principle and Dependency Inversion. The knowledge learnt in these chapters can be transferred to other programming languages which support object orientation. The book also goes into detail about several design patterns, all of which are vital if you are looking to write a large web application or framework in PHP. The book covers the following design patterns:</p>
<ul>
<li>
    Strategy
  </li>
<li>
    Adapter
  </li>
<li>
    Decorator
  </li>
<li>
    Iterator
  </li>
<li>
    Composite
  </li>
</ul>
<p>
A large portion of Part 2 is dedicated purely to testing code. Marcus Baker (one of the authors) is a developer for <a href=http://www.simpletest.org/ id=ez0n title=SimpleTest>SimpleTest</a> (PHP testing library) so all testing examples in the book are focused around it. We are given a gentle introduction to test driven development with some basic examples and explanations on why we should test. We are then given two very detailed examples of how to test a class that interacts with a MySQL database and an email class (which uses mock objects). The third part of the book is focused around user interaction with your PHP web application. It starts off by looking at how and why you should keep your presentation (HTML) code seperate from your logic (PHP) code and then moves on to the Front Controller design pattern. The section is concluded with a form class which validates on both client and server side. The book concludes with a section on representing SQL rows and tables with PHP objects. It takes an indepth look at the Data Mapper pattern and creating a Data Gateway.</p>
<p><font size=4>Opinion</font></p>
<p>It is clear the authors of the book are experienced PHP programmers who participate actively in the community. When explaining the Adapter pattern and seperation of presentation/logic&nbsp; code they use the example of <a href=http://phptal.org/ id=a6oa title=PHPTAL>PHPTAL</a> and <a href=http://www.smarty.net/ id=jhjx title=Smarty>Smarty </a>- two popular and modern templating solutions in PHP. The book is set out very well with clear code examples, well set out headers and helpful class diagrams. The only drawback of the book is that it was published June 30th 2007 so it doesn&#8217;t include features added in PHP 5.2 and 5.3 . While nothing covered in the book is wrong, it&#8217;s unfortunate that topics such as namespaces, anonymous functions and late static binding aren&#8217;t covered. It would have been nice to see a section at the end of the book which brings together all topics that were covered in the book. A basic PHP framework that includes form handling, templating a database layer could have been made. That being said, a tremendous amount of content is covered in great detail and I urge anyone looking to further their PHP knowledge to buy this book.</p>
<p><a href="http://www.amazon.com/PHP-Action-Objects-Design-Agility/dp/1932394753">PHP In Action from Amazon</a></p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-in-action-objects-design-agility/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP Namespaces</title>
		<link>http://query7.com/php-namespaces</link>
		<comments>http://query7.com/php-namespaces#comments</comments>
		<pubDate>Fri, 08 Jan 2010 23:14:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=556</guid>
		<description><![CDATA[<p>Namespaces were introduced into PHP from version 5.3 onwards. They allow the developer to seperate their code into modules or groups which inturn makes the code easier to read. Namespaces prevent class and function name conflicts, it allows you to&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Namespaces were introduced into PHP from version 5.3 onwards. They allow the developer to seperate their code into modules or groups which inturn makes the code easier to read. Namespaces prevent class and function name conflicts, it allows you to have numerous classes with the same name, as long as they are in different namespaces. Namespaces also make the old Zend/PEAR style of class name redundant (Framework_Database_Mysql_Query) because there will no longer be any class name conflicts.</p>
<p>Note: throughout the tutorial we will use the hypothetical files.</p>
<p>/Framework/Database/Mysql/Query.php<br />
/lib/myClass.php<br />
/index.php</p>
<h3>The Basics</h3>
<p>To declare a namespace you simply use the <em>namespace</em> keyword followed by the name of your namespace. You can specify sub namespaces by using the backslash ( \ ). Best practices state that your namespace path should match the directory path. For example the file /Framework/Database/Mysql/Query.php should have the namespace <em>Framework\Database\Mysql</em> and the name of the class should be <em>Query</em>. You should have one namespace and class per file.</p>
<h3>Using Namespaces</h3>
<p>In /lib/myClass.php we declare a namespace, <em>lib</em>, and then define a simple class, myClass. In our index.php file we include the class and instantiate it. Because <em>myClass</em> is in the namespace <em>lib</em>, we must refer to the class as <em>lib\myClass</em>, not just <em>myClass</em>. An alternate way to get namespaced classes is to use the <em>use</em> keyword. By specifying what classes you are <em>use</em>-ing at the top of the script it&#8217;s easy to look back at your code to see the dependencies for each page. You can also <em>use</em> foo <em>as</em> bar. This essentially renames class foo as bar. You&#8217;ll need to do this if you are <em>use</em>-ing two or more classes with the same name (namespaces will be different). Otherwise you will get name errors. Examples below.</p>
<p>/lib/myClass.php</p>
<pre>
namspace lib;

class myClass
{

public function foo()
{
echo 'hello world';
}

}
</pre>
<p>index.php</p>
<pre>
require 'lib/myClass.php';

//Error, Class not found.
$bar = new myClass();

//Displays hello world on the screen.
$bar = new lib\myClass();
$bar->foo();

//Displays hello world on the screen
use lib\myClass;

$bar = new myClass();
$bar->foo();

//Displays hello world
use lib\myClass as newName;

$bar = new newName();
$bar->foo();
</pre>
<h3>Implementing an Autoloader</h3>
<p>Rather than including every file you think you will need in your script, you can implement an autoloader. The autoloader is run every time a class that hasn&#8217;t been defined is called. In our autoload function we can translate a namespace-d class name into a file to include. Assuming we follow the convention of namespaces mapping to directories this is relatively simple.</p>
<pre>
function __autoload($class)
{
    $file = str_replace('\\', '/', $class) . '.php';

    if(file_exists($file))
    {
        require $file;
    }
}
</pre>
<p>So if we called</p>
<pre>$db = new \Framework\Database\Mysql\Query();</pre>
<p>The autoloader would include the file Framework/Database/Mysql/Query.php where (if you were following convention) there would be a class called Query. Notice that the autoload function replaces two backslashes with a foward slash &#8211; even though the namespaces only have singular backslashes. This is because the backslash is the escape character for PHP and by putting two backslashes, it evaluates to one backslash.</p>
<h3>Gotchas</h3>
<p>Built in class names returning as not found.<br />
In your existing code you may use classes built into PHP such as Exception, StdClass, Mysqli etc.. When working with namespaces you must remember to prefix these with the backslash to indicate that you want to use the class from the root namespace, the PHP library &#8211; not your own version of the class that has the same name.</p>
<p>Relative namespaces.<br />
If in /Framework/Database/Mysql/Query.php we needed to use the class in /lib/MyClass.php then you would most likely use the use statement and write something like below.</p>
<p>Query.php</p>
<pre>
namespace Framework\Database\Mysql;

use lib\Myclass;

class Query{}
</pre>
<p>However this will error out. Why? Because PHP is trying to find the class located at \Framework\Database\Mysql\lib\myClass. We need to explicitly define that the namespace path is taken from the root of our application so we prepend a backslash and it will work as intended.</p>
<pre>
namespace Framework\Database\Mysql;

use \lib\myClass;

class Query{}
</pre>
<p>If you have any questions about namespaces in PHP feel free to ask them in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-namespaces/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP cURL</title>
		<link>http://query7.com/php-curl</link>
		<comments>http://query7.com/php-curl#comments</comments>
		<pubDate>Tue, 22 Dec 2009 10:09:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=542</guid>
		<description><![CDATA[<p>cURL is a library written in C that enables easy transfer of data in many different protocols including FTP, FTPS, HTTP, TELNET and LDAP. cURL does more than simply download a file. You can store cookies, upload files, use various&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>cURL is a library written in C that enables easy transfer of data in many different protocols including FTP, FTPS, HTTP, TELNET and LDAP. cURL does more than simply download a file. You can store cookies, upload files, use various types of authentication and tunnel all requests through a proxy. The cURL extension has been bundled with PHP since version 4.0.2 and is enabled by default in php.ini. In this tutorial we will look at the uses of cURL and how it compares to <em>file_get_contents()</em> , we will then write a cURL class which we can use to download the source code of a webpage and download a binary file.</p>
<h3>cURL vs file_get_contents()</h3>
<p>Many PHP scripts require the user to download and then parse the HTML source of a page. When people ask how to do this, the most common reply is to use the <em>file_get_contents() </em>function as it&#8217;s a simple one line solution &#8211; you just need to set the first argument to webpage you want to download and it will return the source code of it. While it may seem very easy to use, it has many pitfalls.</p>
<ol>
<li>cURL is significantly faster than file_get_contents() at retrieving the source of a webpage. It took around 2.3 seconds for file_get_contents() to retrieve the source of google.com while cURL only took 0.65 seconds.  (<a href="http://stackoverflow.com/questions/555523/filegetcontents-vs-curl-what-has-better-performance/555552#555552">source</a>)</li>
<li>Familiarity of code. cURL is implemented in Python, Ruby, Java and many other languages. Your cURL code in PHP will be easily translatable and transferable to other languages, allowing you to save time and money.</li>
<li>cURL allows you to do more. If the webpage were password protected or required a form to be submitted before viewing, this would be possible in cURL. No possible way with file_get_contents().</li>
<li>cURL enables you to remain anonymous while requesting the webpage. You can funnel all cURL requests through one or multiple proxies whereas file_get_contents() will give away the server IP address.</li>
</ol>
<h3>cURL Class</h3>
<p>cURL is only available through procedural functions, there is no cURL class in PHP. Hence scripts that utilize cURL can be messy. By writing a simple class wrapper, we can execute a cURL request in one line &#8211; yet still have the power and configuration of cURL. The class has two public methods. The first <em>getPage()</em> accepts one argument &#8211; the URL of the website. It returns an array of information about the request including the HTML source, content type, time it took to request the page, average download speed and other useful stats. The second downloadFile() accepts two arguments &#8211; the url to the file being downloaded and name of the file it should be saved as. The <em>$options</em> attribute holds the cURL options (that we eventually set using curl_set_opt_array()). A full list of options as well as their descriptions are available <a href="http://php.net/manual/en/function.curl-setopt.php">here</a>.</p>
<pre>class curl
{

public $options = array(
CURLOPT_RETURNTRANSFER =&gt; true,     // return the web page
CURLOPT_HEADER         =&gt; false,    // don't return the headers
CURLOPT_FOLLOWLOCATION =&gt; true,     // follow redirects
CURLOPT_USERAGENT      =&gt; "</em><em>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)</em><em>", // set a normal looking useragent
CURLOPT_AUTOREFERER    =&gt; true,     // set referer on redirect
CURLOPT_CONNECTTIMEOUT =&gt; 120,      // timeout
CURLOPT_TIMEOUT        =&gt; 120,      // timeout
CURLOPT_MAXREDIRS      =&gt; 10,       // stop after 10 redirects
);

public function __construct()
{
}

public function getPage($url)
{

$p = curl_init($url);
curl_setopt_array($p, $this-&gt;options );

$content = curl_exec($p);

if(!$content)
{
throw new \Exception(curl_error($p) . ' ERROR CODE ' . curl_errno($p));
}

$header  = curl_getinfo($p);
curl_close($p);

$header['content'] = $content;

return $header;
}

public function downloadFile($url, $filePath)
{
$fp = fopen($filePath, 'w');

$this->options[CURLOPT_URL] = $url;
$this->options[CURLOPT_FILE] = $fp;

$p = curl_init();

curl_setopt_array($p, $this->options);

$file = curl_exec($p);

curl_close($p);

fclose($fp);

}

}
</pre>
<p>To use the class just instantiate it and call the appropriate methods.</p>
<pre>
$c = new curl();

$c->downloadFile('http://static.reddit.com/reddit.com.header.png', 'logo.png');

//Will download the reddit header image into a file called logo.png

$foo = $c-&gt;getPage('http://www.query7.com');

print_r($foo);
</pre>
<p>Which returns..<br />
<img class="alignnone size-full wp-image-541" title="query7curl" src="http://query7.com/wp-content/uploads/2009/12/query7curl.png" alt="query7curl" width="518" height="385" /></p>
<h3>Useful Reference</h3>
<ul>
<li><a href="http://php.net/curl">PHP.net cURL page</a></li>
<li><a href="http://nz2.php.net/manual/en/function.curl-setopt.php">PHP.net cURL options list</a></li>
<li><a href="http://curl.haxx.se">cURL homepage</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-curl/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Regular expresssion URL Router</title>
		<link>http://query7.com/php-regular-expresssion-url-router</link>
		<comments>http://query7.com/php-regular-expresssion-url-router#comments</comments>
		<pubDate>Tue, 23 Jun 2009 20:30:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=495</guid>
		<description><![CDATA[<p>In this tutorial we will create a PHP URL router. The developer using the router will be able to define these routes with regular expressions, these will then map to a file, class and method which will be called &#8211;&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we will create a PHP URL router. The developer using the router will be able to define these routes with regular expressions, these will then map to a file, class and method which will be called &#8211; very similar to Django&#8217;s routing. By using regular expressions to define our URLs we get maximum customizability. <em>/class/method/</em> based URL routing is too restrictive sometimes. We will assume the user is using an apache or similar web server with <em>mod_rewite</em> enabled. You can adapt this router and use it in your web application or framework.</p>
<p>Quick Note: This is taken straight out of one of my applications. I have a singleton registry object called $core which you&#8217;ll see referenced many times. I suggest you make your own or use <em>global</em> variables.</p>
<h3>.htaccess</h3>
<p>First of all we need to create a <em>.htaccess</em> file in the root directory of your project. We turn the RewriteEngine on, and then declare a rule to route everything except images/js/css through our <em>index.php</em> file. So even if the person goes to www.yoursite.com/directory/file.php , rather than executing that file it will execute our <em>index.php</em> instead.</p>
<pre>RewriteEngine on
RewriteRule !\.(js|ico|txt|gif|jpg|png|css)$ index.php</pre>
<p>If your building a framework or application you&#8217;ll probably have some ini/bootstrapping code that you want to run here. The router itself is procedural so include it at the bottom of index.php.</p>
<h3>Declaring the Routes</h3>
<p>We define our routes in an array called <strong>$urls</strong> (naming matters). You can declare these anywhere before the router is included. In the array key we declare our regular expression. I&#8217;ve listed a couple as examples below. The first matches to the root &#8211; as if someone went to www.yoursite.com. This gets mapped to <em>application/views/blog.php</em> , then the <em>index()</em> method in the <em>blog</em> class is executed. The second is slightly more complex and captures a value called slug. This value is then passed as a parameter in the <em>individual_post()</em> method when it is executed.</p>
<pre>$urls = array(
			// "Regex to match" =&gt; "path_to_file.php___className___functionName",

			"(^[/]$)" =&gt; "application/views/blog.php___blog___index", // No captured values
			"(/post/(?P &lt;slug&gt;\w.*)$)" => "application/views/blog.php___blog___individual_post",

			);</pre>
<h3>The Router Itself</h3>
<p>The operation of the router itself is pretty simple:</p>
<ul>
<li>Figure out the URI the user requested</li>
<li>Try and match one of the defined regular expressions to that URI</li>
<li>If it does match, see if there are any captured matches (eg. our slug name above)</li>
<li>If there are matches, call the appropriate method and pass them as a parameter</li>
</ul>
<p>First we need to figure out the URI. For example if they went to www.yoursite.com/blog/first-post/ , we would just want to capture the /blog/first-post/ so it matches our regular expressions. The code below does that with a series of <em>str_replace()</em>s.</p>
<pre>
$already_there = str_replace('index.php', '', $_SERVER['SCRIPT_NAME']);

$slightly = str_replace($_SERVER['SCRIPT_NAME'], "", $_SERVER['REQUEST_URI']);

$uri = '/' . str_replace($already_there, '', $slightly);
</pre>
<p>We will then iterate through our defined URL routes/regular expressions and try to get a match.</p>
<pre>foreach($urls as $regex => $mapper)
{

	if (preg_match($regex, $uri, $matches))
	{
</pre>
<p><em>$matches</em> is an array that is populated when a URL pattern is matched. If we are capturing a value (eg. slug in the above example) then there will be a key called &#8216;slug&#8217; and the value it captured in the array. If there is only one item in the <em>$matches</em> array, then there the user didn&#8217;t try to capture any values in their regular expression so we don&#8217;t need to pass any arguments in the method that we call. We simply explode the $val variable to get the filename, class name and method name, then call it.<br />
If however we iterate across a key that isn&#8217;t numeric, then we know there is a value that is getting captured. We simply get that and pass it as an argument when we call the method.</p>
<pre>
		foreach($matches as $key => $val)
		{

			if(count($matches) == 1)
			{

				$foo = explode("___", $mapper);

				//Include the view they specified
				include($core->settings->application_path . $foo[0]);

				//Instantiate a new class they specified
				$bar = new $foo[1]();

				//Call the function they specified
				$bar->$foo[2]();

			}

			//Make sure the key is not numeric - some extra garbage preg_match() gives us.
			if(!is_numeric($key))
			{

				//Split the value they defined up into sections
				$foo = explode("___", $mapper);

				//Include the view they specified
				include($core->settings->application_path . $foo[0]);

				//Instantiate a new class they specified
				$bar = new $foo[1]();

				//Call the function they specified
				$bar->$foo[2]($val);

				//echo $key . ' -> ' . $val . '';
			}
		}
	break;
</pre>
<p>Theres also a place to indicate to the user that there we no matches &#8211; it&#8217;s up to you if you want to give a custom error page, 404, whatever.</p>
<pre>
	}
	else
	{
	    //echo "A match was not found.";
	}

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-regular-expresssion-url-router/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Autoload</title>
		<link>http://query7.com/php-autoload</link>
		<comments>http://query7.com/php-autoload#comments</comments>
		<pubDate>Sat, 30 May 2009 12:33:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=482</guid>
		<description><![CDATA[<p>In large PHP applications you typically see a &#8220;classes&#8221; directory that only contains classes which are used throughout the application (database, session management, forms etc..). A problem quickly appears: Everytime you wanted to use one of the classes, you would&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In large PHP applications you typically see a &#8220;classes&#8221; directory that only contains classes which are used throughout the application (database, session management, forms etc..). A problem quickly appears: Everytime you wanted to use one of the classes, you would be forced to <em>include()</em> it at the top of the page. <em>__autoload()</em> solves this by automatically including the definition file when a class is called.</p>
<h3>Example</h3>
<p>We have a simple application with the index.php file in the root directory and a directory called classes that contains numerous classes.<br />
<strong>classes/time.class.php</strong></p>
<pre lang="php">class time
{
	function fn1()
	{
		echo 'hello world';
	}
}</pre>
<p>The code below shows what we&#8217;d need to do if we didn&#8217;t have autoload. While that code doesn&#8217;t seem so bad, imagine writing includes on each of your 30-40 files. It would get messy and very hard to maintain. Another option would be to have a single file that all of your classes are included in, there include that one file in each of your functional scripts but you could expect a performance loss as every one of your classes would be included on the page &#8211; even if it wasn&#8217;t needed.</p>
<p><strong>index.php</strong></p>
<pre lang="php">include('classes/time.class.php');

$time = new time();

$time-&gt;fn1();

//Returns hello world</pre>
<p>The<em> __autoload()</em> function accepts one parameter &#8211; the name of the class that is being instantiated. We pass this so we know what file to include.</p>
<p><strong>index.php revised</strong></p>
<pre lang="php">function __autoload($class_name)
{
	include('classes/' . $class_name . '.class.php');
}

$time = new time();

$time-&gt;fn1();

//Returns hello world</pre>
<h3>A More Complex Example</h3>
<p>Large projects and frameworks often have classes split up into groups &#8211; extensions, modules and core components. When instantiating a new class, we don&#8217;t want to have to declare what group it belongs to. We can build this right into our autoload function, and also check if the file/class exists.</p>
<pre lang="php">function __autoload($class)
{

	if(file_exists('core/' . $class . '.class.php'))
	{
		include('core/' . $class . '.class.php');
	}

	if(file_exists('extensions/' . $class . '.class.php'))
	{
		include('extensions/' . $class . '.class.php');
	}

	if(file_exists('modules/' . $class . '.class.php'))
	{
		include('modules/' . $class . '.class.php');
	}

}</pre>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-autoload/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy RSS Consumption with Simple Pie in PHP</title>
		<link>http://query7.com/easy-rss-consumption-with-simple-pie-in-php</link>
		<comments>http://query7.com/easy-rss-consumption-with-simple-pie-in-php#comments</comments>
		<pubDate>Sun, 01 Feb 2009 06:16:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=350</guid>
		<description><![CDATA[<h2>Introduction</h2>
<p>RSS Feed consumption has always been a stick point in PHP. Simple Pie is a library that works with both PHP4 and PHP5 that enables you to easily parse and save RSS feeds. Today I&#8217;ll show you some common&#8230;</p>]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>RSS Feed consumption has always been a stick point in PHP. Simple Pie is a library that works with both PHP4 and PHP5 that enables you to easily parse and save RSS feeds. Today I&#8217;ll show you some common uses of Simple Pie and explain how it runs.</p>
<p>Simple Pie requires:</p>
<ul>
<li>PHP 4.3.0 or higher</li>
<li><a href="http://nz.php.net/curl">cURL</a> Enabled.</li>
<li><a href="http://nz.php.net/zlib">zLib</a> (Caching?)</li>
</ul>
<p>As well as a few other PHP modules that will be enabled in a vanilla PHP install. To run the compatibility test, upload the un-compressed archive to your server and navigate to www.yourname.com/pathtosimplepie/compatibility_test/sp_compatibility_test.php .</p>
<h2>Finding the RSS Feed</h2>
<p>The first thing we need to do is include SimplePie and then make a new SimplePie feed.</p>
<pre>include('path/to/simplepie.inc');</pre>
<pre>$feed = new SimplePie('lastkarrde.com');</pre>
<p>Simple Pie has a very useful &#8216;auto feed discovery&#8217; feature. If you give it a plain URL, such as Query7.com, it will automatically find the RSS feed. Of course you can specify the path to the .xml file or Feed Burner page if you wanted to. Although the feed has been pulled we need to do call on another function, handle_content_type, to ensure that the feed has the correct mime type and encoding.</p>
<pre>$feed-&gt;handle_content_type();</pre>
<h2>Parsing the RSS Feed</h2>
<p>Now that all of the configuration/setup is done (all 3 lines of it) we can parse the feed on our page. We use a <em>foreach</em> loop to iterate through all of the items. Simple Pie&#8217;s functions make everything easy! As you can see below we simply echo the date, content and title of each item in the RSS feed.</p>
<pre>foreach($feed-&gt;get_items() as $item){

echo '&lt;h3&gt;&lt;a href="' . $item-&gt;get_permalink() . '"&gt;' . $item-&gt;get_title() . '&lt;/a&gt;&lt;/h3&gt;';
echo '&lt;p&gt;' . $item-&gt;get_date() . '&lt;/p&gt;';
echo '&lt;p&gt;' . $item-&gt;get_content() . '&lt;/p&gt;';

}</pre>
<p><a href="http://query7.com/wp-content/uploads/2009/01/preview1.gif"><img class="alignnone size-full wp-image-354" src="http://query7.com/wp-content/uploads/2009/01/preview1.gif" alt="" width="500" height="190" /></a></p>
<h2>Extra Data from the Feed</h2>
<p>In the above example we only got the permalink, title, date and content from each feed item. Simple Pie provides alot of other functions that are used in the same way. Some of the more useful ones are.</p>
<ul>
<li><strong>get_author(s)</strong> &#8211; Get the author(s) of the post item (if set).</li>
<li><strong>get_description</strong> &#8211; Gets a summary of the post content, rather than the whole post like get_content() does.</li>
<li><strong>get_source </strong>- Returns the source site of the feed. This is particularly useful if you are parsing multiple feeds and displaying them on one page.</li>
<li><strong>get_title</strong> &#8211; Returns the title of the entire RSS feed, wouldn&#8217;t be called in the loop.</li>
</ul>
<h2>Parsing Multiple Feeds onto one Page</h2>
<p>With Simple Pie, this is painfully easy. When declaring a new instance of the Simple Pie class, we pass an array of websites rather than a string. Instead of..</p>
<pre>$feed = new SimplePie('lastkarrde.com');</pre>
<p>We would use</p>
<pre>$sites = array('query7.com', 'digg.com', slashdot.org');
$feed = new SimplePie($sites);</pre>
<h2>Caching</h2>
<p>Simple Pie comes with an easy to use and very effective caching system. By default it caches each feed for 60 minutes, then it automatically discards it and pulls a new copy of the feed. This is great for a &#8216;typical user&#8217; who just wants to use Simple Pie for a few things but for someone who knows the feed they are monitoring updates every 2 hours.. or every 20 minutes you need to change the length of caching time. This is done with the <em>set_cache_duration()</em> function. You specify it after you have pulled the feed, but before you display any information onto the page. You can also change the location of where the feed is cached with the <em>set_cache_location()</em> function. Both are demonstrated below.</p>
<pre>$feed = new SimplePie('query7.com');
$feed-&gt;set_cache_duration(1800); //Value in seconds, 1800s = 30 minutes
$feed-&gt;set_cache_duration('/home/user/simplepie/customcache'); //Full path to cache

//Continue with display code here.</pre>
<p>As you can see Simple Pie makes parsing RSS feeds really easy. You don&#8217;t have to parse them directly onto the page, you can just as easily put database INSERTs into the loop rather than echos and display them from the database at a later date. Simple Pie is an open source project so you don&#8217;t need to worry about any fees or license agreements.</p>
<p>If you have any questions about Simple Pie, feel free to post them below.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/easy-rss-consumption-with-simple-pie-in-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial: Automated Site Backup with PHP and FTP</title>
		<link>http://query7.com/tutorial-automated-site-backup-with-php-ftp</link>
		<comments>http://query7.com/tutorial-automated-site-backup-with-php-ftp#comments</comments>
		<pubDate>Sun, 25 Jan 2009 11:24:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=339</guid>
		<description><![CDATA[<p>In this tutorial we are going to make a PHP script that archives your website into a .tar file, then automatically moves it to an external FTP server for safe keeping. We can then setup a cron for this script&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we are going to make a PHP script that archives your website into a .tar file, then automatically moves it to an external FTP server for safe keeping. We can then setup a cron for this script which will execute it automatically every day/week/month , however frequent you want it. This will only work on Linux servers however that shouldn&#8217;t be a problem as most hosts run Linux.</p>
<p>First we&#8217;ll setup some variables to allow for easy editing.</p>
<pre>$dir = '/path/to/file'; // Directory to backup.
$filename = 'backups/backup' . date("MdY") . '.tar'; //path to where the file will be saved.

$ftp_server = 'urlToFTPServer.Com'; //External FTP server
$ftp_user_name = 'ftpUsername'; //External FTP server username
$ftp_password = 'ftpPassword'; //External FTP server password</pre>
<p>Now we need to archive the site. We&#8217;re going to wrap an if statement around it so if for some reason it doesn&#8217;t archive, the FTP part of the script won&#8217;t try and copy it over to another server. The <em>system</em> function executes a system command, here we are calling <em>tar cvf</em> which will archive our <em>$dir</em> (directory) and save it to the path specified in <em>$filename</em>.</p>
<pre>if(system("tar cvf $filename $dir")){</pre>
<p>We&#8217;ll then connect to the FTP server itself. Because we set variables, if we need to change servers, it&#8217;s very easy to implement.</p>
<pre>$conn_id = ftp_connect($ftp_server);

$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_password);</pre>
<p>If it connects to the server, then we can move our backup across. We give it the same name as the archive on our own server and store it in a /backups directory.</p>
<pre>if (($conn_id) || ($login_result)) {

$upload = ftp_put($conn_id, 'backups/' . date("MdY") . '.tar', $filename, FTP_BINARY);

    }</pre>
<p>Once that is done, we can close the FTP stream as we don&#8217;t need to use it anymore.</p>
<pre>ftp_close($conn_id);
} //Initial if statement</pre>
<p>All thats needed to do is automate this script. For this we use something built into the Linux Operating System called a Cron Tab. Crons will automatically run a script at a time you specify. We can set it up to run every time at the same day so you have a daily backup. You can make this more frequent or less frequent depending on how often the data of your site changes. Making a <a href="http://www.upstartblogger.com/how-to-create-a-cron-job-in-cpanel">cronjob in cPanel</a> is alot easier than if you <a href="https://help.ubuntu.com/community/CronHowto">didn&#8217;t have cPanel</a>. But both are fairly straight foward.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/tutorial-automated-site-backup-with-php-ftp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP/jQuery Todo List Part 2</title>
		<link>http://query7.com/php-jquery-todo-list-part-2</link>
		<comments>http://query7.com/php-jquery-todo-list-part-2#comments</comments>
		<pubDate>Mon, 08 Dec 2008 04:24:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=280</guid>
		<description><![CDATA[<p>This is part 2 of a 2 part series on making a Todo List with PHP and enhancing it with jQuery&#8217;s AJAX</p>
<p>In part 1 of the tutorial, we covered the PHP and MySQL side of things. In this part&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>This is part 2 of a 2 part series on making a Todo List with PHP and enhancing it with jQuery&#8217;s AJAX</p>
<p>In part 1 of the tutorial, we covered the PHP and MySQL side of things. In this part we will be enhancing it with jQuery&#8217;s AJAX and manipulation functionality. The to-do list will degrade fine &#8211; if the user has Javascript disabled, the application will still work. All changes occur in the <strong>index.php</strong> file.</p>
<p>There are two parts to the script. One handles the posting of new posts, while the other handles posts being deleted. We&#8217;ll start with adding new posts.</p>
<pre>//When the button with an id of submit is clicked (the submit button)
$("#submit").click(function(){

//Retrieve the contents of the textarea (the content)
var formvalue = $("#content").val();

//Build the URL that we will send
var url = 'submit=1&amp;content=' + formvalue;

//Use jQuery's ajax function to send it
 $.ajax({
   type: "POST",
   url: "process.php",
   data: url,
   success: function(){

//If successful , notify the user that it was added
   $("ul").before("&lt;p class='new'&gt;You just added: &lt;i&gt;" + formvalue + "&lt;/i&gt;&lt;/p&gt;");

   }
 });

//We return false so when the button is clicked, it doesn't follow the action
return false;

});</pre>
<p>The <em>url</em> part confuses some people. What we are doing is sending a request to the process page, we need to include some data with that request. In process.php there was the line</p>
<pre>if($_POST['submit']){</pre>
<p>It checks to see if $_POST['submit'] isn&#8217;t null (has a value). If it is null (has no value), then it means that the form hadn&#8217;t been submitted, by sending any value, in our case <em>submit=1</em>, we are telling process.php that the button had been clicked so it should run the rest of the PHP script. The rest of the PHP script calls for the content, which we also send in the url (<em>content= &#8216; + formvalue</em>). Instead of sending anything, we only want to send the value of the form (The stuff inside the textarea &#8211; that the user wants to submit). By returning false at the end, it prevents the submit button from carrying through with its <em>action=&#8221;process.php&#8221;</em>. If it did, it means the page would refresh when the information was sent which is exactly what we don&#8217;t want.</p>
<p>The code that handles the deletion of posts is similar.</p>
<pre>//Check to see if an anchor link was clicked (The delete link)
$("a").click(function(){

//Save the link in a variable called element
var element = $(this);

//Find the id of the link that was clicked
var noteid = element.attr("id");

//Built a url to send
var info = 'id=' + noteid;

 $.ajax({
   type: "GET",
   url: "delete.php",
   data: info,
   success: function(){
   element.parent().eq(0).fadeOut("slow");
   }
 });

//We return false so the browser doesn't actually follow the link
return false;

});</pre>
<p>When we were displaying the posts in <strong>process.php</strong> we echo&#8217;d the id of the post in the anchor tag. We are then getting this id <em>element.attr(&#8220;id&#8221;)</em> and building the URL. So when the AJAX call is sent, it will be something like <em>delete.php?id=POSTID. </em>If the AJAX call is successful, then we need to hide the list item.</p>
<pre>element.parent().eq(0).fadeOut("slow");</pre>
<p>In that bit of code, we select the element (anchor tag) that was clicked. We then find it&#8217;s parents and take the first one using <em>eq(0)</em>. It&#8217;s &#8216;first&#8217; parent is the list item its in (&lt;li&gt;&lt;a href&gt;&lt;/a&gt;&lt;/li&gt;) and we fade that out slowly.</p>
<p>Demo: <a href="http://lastkarrde.com/q7todo/">http://lastkarrde.com/q7todo/</a></p>
<p>Download: <a href="http://lastkarrde.com/files/q7todo.zip">http://lastkarrde.com/files/q7todo.zip</a></p>
<p>You can read the first part of the series at <a href="http://query7.com/php-jquery-todo-list-part-1/">PHP + jQuery Todo List Part 1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/php-jquery-todo-list-part-2/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
