Tag Archives: PHP

First time using Smarty Template Engine – where to put the template directory?

I decided to give the Smarty Template Engine a go tonight. I downloaded it pretty easily and moved it to my htdocs folder to try out. My initial impression of the code was that it was pretty powerful and I was going to enjoy working with it. When I loaded it up on the browser though I was faced with some error messages. Not one likes to see errors when they haven’t even started writing their own code!

So I started down the “winging it” road and decided I would learn from doing and reading the demo code (even though it wasn’t working yet).

The first step is to create a test directory. My path was to C:\xampp\htdocs\smarty\test\ (I left the /lib/ directory that contains the core Smarty code in the parent directory, /smarty/. Now the thing to note is that for all intensive purposes, your web site or application is going to live inside this /test/. So when a tutorial says to create a /templates/ folder, it should be at C:\xampp\htdocs\smarty\test\templates\. It will become a bit more evident as you start using Smarty more and more, but essentially that is the standard. When you go to include a template file you are able to call just the file name. If you had put the template directory in a parent or sibling folder, you would need to use relative or absolute paths to prepend the file name.

- htdocs
   - smarty
      - lib
      - test
         - templates

Posting with cURL

I like to browse Stackoverflow in my spare time to learn new things. I came upon this post about posting with cURL recently and though it was worth sharing.

The question was about whether you needed to urlencode parameters being posted. I can’t say I had ever run into any problems posting with cURL before, but I was still curious of the answer.

The top answer referenced the PHP manual:

This parameter can either be passed as a urlencoded string like ‘para1=val1&2=val2&…’ or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data.

I realized the reason I had never run into any problems was that I use an array to pass my values about 90% of the time. So PHP had been processing and encoding the parameters for me this whole time, which is what I figured it had been doing. What I didn’t know was that had I been passing one value as a string, PHP would NOT be encoding that value for me. So make a mental note that when posting using cURL either use an array to store the parameters or else you need to urlencode() your value!

SimpleXMLElement instead of a string being returned

I’ve been working on integrating http://square-a-day.tumblr.com for my girlfriend, Lindsay Webster‘s site. One road block I ran into was that Tumblr has a cap on the number of items you can pull from their XML feed set at 50. That isn’t a terribly big problem though because within the XML feed there is an attribute ‘total’ that will come in handy.

The difficulty in retrieving the total attribute

I haven’t full on worked with the PHP5 SimpleXML class in about a year so I was a bit rusty to start with. I quickly put together the following code to garner the first 50 posts and also to retrieve the total number made on the Tumblr account (although for debugging purposes I only retrieve 2).


// Use cURL to retrieve the XML feed for the site
function getSquares($start=0,$num=50){
			$tumblrLink = 'http://square-a-day.tumblr.com/api/read?start='.$start.'&num='.$num;
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $tumblrLink);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			$data = curl_exec($ch);       
			curl_close($ch);
			
			return new SimpleXMLElement($data);
		}
		// This is a SimpleXMLElement object now
		$tumblrXML = getSquares(0,2);
		
		$total = 50;
                // Lock in on each of the posts nodes (should just be one) and extract any of the attributes for it
		foreach ($tumblrXML->posts->attributes() as $key=>$val){
                        // We are only concerned with the total right now so only track that
			if($key == 'total'){
				$total = $val;
                                break; // End the loop once we have found it
			}
		}
		
		print_r($total);

So the above should print out the total number of squares. Instead I get the following:

SimpleXMLElement Object ( [0] => 98 ) 

I had never seen such a thing before and I wasn’t even sure how to access it. I tried reading through the docs and finally I hit on something in the SimpleXML examples page. Juan Herrera wrote, “When using simplexml to access a element the returned object may be a SimpleXMLElement instead of a string.” He also linked to a bug report where it was declared this was intentionally done. I can’t find any further information on it was done this way, but they did thankfully give a helpful method of fixing it, type casting. If you remember that foreach statement I had, I only had to make one minor adjustment to it to make things work.

		foreach ($tumblrXML->posts->attributes() as $key=>$val){
                        // We are only concerned with the total right now so only track that
			if($key == 'total'){


				$total = (string)$val;


                                break; // End the loop once we have found it
			}
		}
		
		print_r($total);

Parsing an e-mail message with PHP’s IMAP functions

First you need to setup the connection to the mailbox, Google has a pretty good intro on finding the hostname for a Gmail mailbox.

<?php
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'replies@lewiscreekbuilders.com';
$password = '6aDr#qE=';

// Initial connection to the inbox
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

// Grabs any e-mail that is not read
$emails = imap_search($inbox,'UNSEEN');

if($emails) {
   foreach($emails as $email_number) {
	$message = imap_fetchbody($inbox,$email_number,1.1);
	if ($message == "") { // no attachments is the usual cause of this
	    $message = imap_fetchbody($inbox, $email_number, 1);
	}
				
	print_r($message);

   }// end foreach loop
} // end if($emails)
?>

The biggest trouble I had when trying to parse the messages was that if I simply called for the message in part 1 (like on line 16 above), it would return the plain text version of the e-mail… which includes MIME type headings and so forth. Very hard to anticipate for and to parse out.

After doing some reading online, which included the PHP docs, I came across these two useful pages. PHP doc on the imap_fetchbody function and I found this article on Tux Radar about Dealing with MIME-encoded messages. The parts of a message vary depending on what is being sent. An e-mail with an attachment, for example, has a different part 1 than an e-mail with no attachment.

With an email message that only has a text body and does not have any mime 
attachments, imap-fetchbody() will return the following for each requested 
part number:

(empty) - Entire message
0 - Message header
1 - Body text

With an email message that is a multi-part message in MIME format, and contains
the message text in plain text and HTML, and has a file.ext attachment, 
imap-fetchbody() will return something like the following for each requested 
part number:

(empty) - Entire message
0 - Message header
1 - MULTIPART/ALTERNATIVE
1.1 - TEXT/PLAIN
1.2 - TEXT/HTML
2 - file.ext

Now if you attach the above email to an email with the message text in plain 
text and HTML, imap_fetchbody() will use this type of part number system:

(empty) - Entire message
0 - Message header
1 - MULTIPART/ALTERNATIVE
1.1 - TEXT/PLAIN
1.2 - TEXT/HTML
2 - MESSAGE/RFC822 (entire attached message)
2.0 - Attached message header
2.1 - TEXT/PLAIN
2.2 - TEXT/HTML
2.3 - file.ext

- Courtesy of the PHP docs

Hopefully my code above starts to make more sense now that you see a chart of the different parts of an e-mail. I first check for part 1.1 as that included the plain text e-mail (the message being sent), if there is nothing there I revert to checking part 1. I found that most of the time if 1.1 was empty it was because there was no attachment with the e-mail.

Opinion of CakePHP from someone who started learning rails a few months back

When I started learning rails back in June I thought to myself, “This is fantastic, why have I never used this before.” Everything has a spot and there are so many cool tools to streamline development so I can focus on the logic behind the code rather than fixing a bug with a form that resulted from an omitted tag.

Recently I decided to plunge into CakePHP and see what all the fuss was about. I was expecting to find a framework with thousands of files and no documentation. I found quite the opposite to be true. As I read and worked through some examples I started making so many connections to the Rails lessons and books I had been reading.

Model View Controller (MVC)

Rails is not the only Model, View, and Controller based language/framework, but it is the first one I worked with that did it well. I was able to clearly see and work with Rails whereas I had difficulty doing so with various PHP4/5 MVCs I had toyed with over the years. Perhaps it was the experience from working with those that I was able to arrive at the realization that Rails was structured so well.

The features

CakePHP has many of the same features as Rails: Scaffolding, Routes, Activerecord (although not called this in CakePHP), and lastly the file size is kept to a minimum. There was not thousands of files to work with, there is around 900 (which when compared with a comparable Rails app, is about four times as large).

What did I really like about CakePHP?

  • File structure
  • Model relationships (similar to ActiveRecord in Rails)
  • Helper classes (html, forms, cache, rss, paginator, etc…)
  • The documentation.

There is bountiful amounts of information on the CakePHP web site to instruct you, and it is all displayed in a pleasing manner. I found the blog tutorial to be a great intro to the framework.

What did I not like so much about CakePHP?

  • Number of files.

Although not a large amount of files compared to some other MVC frameworks for PHP, I still felt as though there were area for improvement. Perhaps being able to pick and choose what helpers you want active on the site would help to trim some fat down. To compare it again to a Rails application, there are about 900 files in a recent CakePHP whereas a similar Rails application has but 200.

Overall opinion

Having just started using CakePHP I do think it is extremely useful for anyone who wants to dive into Rails at some point. It is similar in many respects and can start molding your brain to think in Rails before you ever need to. I can definitely see myself using CakePHP in the future on personal and professional projects.

How I used PHP’s magic methods and why

When PHP5 was released there were a couple new additions, magic methods. The best way to think about a magic method is a function you didn’t have to write or include that helps keep your code running smoothly.

A couple of the many magic methods

__set() and __get() were used to create some neat functionality for this site.

__set()

Normally when setting variables for use on a page you need to declare each and every one of them. When doing so this invokes the __set() magic method. What happens if you try and set a variable that you don’t know the name of or if it may not always exist? To use a real example, I was setting properties in my Template class that were ever changing.

Class Template {
private $vars = array();

public function __set($index, $value)
{
  $this->vars[$index] = $value;
}
 

When I try and set a property that does not exist, such as $this->page_id = 6;, the Template class invokes the __set($index, $value) method which results in $this->vars[page_id] = 6 being set.

__get()

The converse of the __set() method is __get(), which is invoked when you try and retrieve a variable or property that is either not set or not accessible.

Because in my above example $this->vars is private, it is inaccessible from other classes. If I wanted to change this functionality I would need to essentially change how the __get() method works, or overload it.

  public function &__get($index)
 {
        return $this->vars[$index];
 }

If I had this code in my Template class I would then be able to reference the vars property from another class. The ampersand before __get() means to use references when working with the variables. When you pass by reference it is best to forget about the value of the variable and think more about what the variable holds. Changing the value of a variable when you pass it by reference changes the value of the variable outside of the function/method as well. It is often used to ‘return’ multiple values without actually using the return keywords. I touched on passing by reference in a past post.

Passing by reference in PHP

I was just reading up on some PHP while I work on one of my final projects and I came across the topic of passing by reference. Which if you are not familiar with it, this is the PHP.net reference page. I had no idea that it existed and it instantly reminded me of the past three weeks of C++ where we have been discussing and using pointers as a means of “returning” more than one value from a function.

A good explanation of a reference is:

“References are a way to have multiple variables referencing the same variable container using different names — so whatever name you’re using an operation on that variable will always have an effect on the others.” – Johannes Schlüter

My experience with pointers and passing by reference has been in the classroom and so the only benefit I have seen is that you can modify variables outside of a function. Check this snippet out for instance:

function addOne(&$input){
$input++;
}
$var = 1;

addOne($var);

//returns 2.

Conclusion

I don’t know that I would really pass by reference outside of the classroom at this stage as I have not encountered a situation where I needed to return or modify more than one value at a time.

Cookie doesn’t set using PHP 4, but they do using PHP5?

So yesterday when working on a client site all of the cookies stopped working. I had not changed a single thing since I had last worked on it and everything worked. I did some research for a couple hours where people wrote about cookies not setting properly. It yielded a vast amount of results, mostly pointing to how I was setting the cookie. My cookie code appeared to be perfect in structure though so I cast that aside.

setcookie("cookieName", '1' , time()+7200,'/','.levijackson.net');

The best answer I could fine over the two hours was this:

Check the cookie settings of the other browsers and if they’re set to block all or empty on exit.
If the cookies work in one browser, but not another, you will need to make sure that the other browser is letting you set cookies in the first place.
Sometimes it will look like you can create the cookie, but then it will disappear or be deleted with each page reload.

It’s also possible that because you’re setting the cookies in an iframe, that the browsers may view it as a third-party cookie and reject it unless explicitly set out in the browser preferences to allow third-party cookies.

In that case you would need a compact privacy policy (or a compact P3P header) on the pages from where you’re trying to set the cookies from.
For PHP, you would add this as your header for the page setting the cookie:
header(‘P3P:CP=”IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT”‘);

Posted on Stackoverflow

The problem?

It didn’t work for me. For one, I wasn’t using iframes and therefore had no path issues. I also came across another solution of using httpOnly cookies. This solved the problem in Chrome but not IE. I depend on expiring and resetting cookie values for a key part of the site. This didn’t have the functionality of expiring from what I could find.

I always use it as my last option, as I like to figure things out on my own, but I finally turned to Stackoverflow. A user on the site, Kip, suggested I use Web Sniffer to see how the headers were being sent. When I viewed them I at first didn’t notice anything different. I was getting the following:

<em>(PHP 4 site)</em> eventCookie=2; expires=Wed, 30-Sep-2009 02:16:37 GMT; path=/; domain=.levijackson.net <br />
<em>(PHP 5 site)</em> eventCookie=2; expires=Wed, 30 Sep 2009 05:33:37 GMT; path=/; domain=.levijackson.net <br />

The part that finally clicked with me was when the cookies expired. For the PHP 5 site the cookie expired 5:30am GMT which was the equivalent to around midnight here (at the time of testing it was around 11pm). The cookie for the PHP 4 site however was set to expire around 2am GMT which translated to 9pm. As a result the cookie was setting and immediately unsetting.

The solution:

I set the cookie to expire in 24 hours rather than just 2. This allowed for the difference in server time.

Side notes:

I still don’t know how the server changed its time, but it quite literally went from working to not working. So I can only assume the admin of the server either updated or changed a setting. Either way I gained a tool and some more knowledge of cookies so I can’t complain.