Skip to content
set 1 10

Test-Driven Development with CakePHP 1.3 TDD

by Vinícius Krolow

Today I found a good article about TDD, Test Driven Development using CakePHP 1.3. Nowadays with the constantly changes of scope in one web project the TDD is something that all programmer must know and practice, and some frameworks like the CakePHP give the support for that.

In a recently article for the php architect magazine, Carl Anderson describe a great article how to use the TDD inside the CakePHP 1.3.

You can download that tutorial by free here

ago 16 10

PHP get the current money quote

by Vinícius Krolow

A simple example to get the money quote using the Finances of yahoo. In the example Euro to Reais.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< ?php
	function get_content($url) {
		$ch = curl_init();
		$timeout = 5; 
		curl_setopt ($ch, CURLOPT_URL, $url);
		curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
		$file_contents = curl_exec($ch);
		curl_close($ch);
 
		return $file_contents;
	}
 
      	setlocale(LC_MONETARY, 'pt_BR');
	$euro = explode(',', get_content('http://download.finance.yahoo.com/d/quotes.csv?s=EURBRL=X&f=sl1d1t1ba&e=.csv'));
 
	echo '1 euro vale R$ ' . money_format('%i', $euro[1])  . '. Atualizado às '. $euro[3] .' Fonte: Yahoo Finances';
?>

With this code I made two twitter accounts to inform to me the money quote those are, cotacaoeuro and cotacaodollar.

ago 16 10

PHP tip: PHP how many days in a month?

by Vinícius Krolow
1
2
3
< ?php
echo cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y')), ' days.';
?>

Read about the function.

ago 16 10

PHP Query the jQuery in PHP: Building a simple PHP crawler using it

by Vinícius Krolow

The CSS3 selectors power using PHP, that is fantastic is not it? Well I was suppose to use XPATH with DomDocument always when I need filter some HTML, but the idea to make a class that understand CSS3 patterns and return the Dom object that match with the rule, always pass in my mind, someday ago I was decide to initialize one class to do that but before I thought let’s look for before, and I found what I needed and it was a great job made by Tobiasz Cudnik, the project is called phpQuery, a library written in PHP5 and also provides a Command Line Interface.

Let’s show the power of phpQuery, I’ll do a kind of crawler not so smart just to show the power of phpQuery, to do that I’ll create a simple structure of class to give to flexibility to the code:

Crawler.php, a Class that make request for URL’s that we pass!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
< ?php
 
require 'phpQuery.php';
 
class Crawler {
 
	public $content;
 
	public function __construct() {
	}
 
	protected function request($url, $contentType = 'utf-8') {
		$this->content = $this->get_content($url);
		phpQuery::newDocument($this->content);
		return $this->content;
	}
 
	private function get_content($url) {
		$ch = curl_init();
		$timeout = 5; 
		curl_setopt ($ch, CURLOPT_URL, $url);
		curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
		$file_contents = curl_exec($ch);
		curl_close($ch);
 
		return $file_contents;
	}
 
}
?>

CrawlerInteface.php, An inteface to define the methods of each crawler class will have

1
2
3
4
5
6
7
< ?php
interface CrawlerInterface {
 
	public function getData();
 
}
?>

CrawlerFactory.php, The class that call the implemented classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
< ?php
require 'Crawler.php';
 
abstract class CrawlerFactory {
 
	private $className;
	private $args;
 
	public static function factory($className, $args = array()) {
		if (is_file(dirname(__FILE__) . '/Crawler' . $className . '.php')) {
			require_once 'Crawler' . $className . '.php';
 
			$class = new $className(implode(',', $args));
 
			return $class;
		} else {
			throw new Exception('Is not a valid class');
		}
	}
}
?>

Well I created the crawler class that make the request to get the content also a common interface for each site that we want to get the content, and the factory class that will call the classes that we implement for each site.

Let’s build a simple feed class, will read the items from RSS for one blog.

CrawlerCobaia.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
< ?php
require 'CrawlerInterface.php';
 
class Cobaia extends Crawler implements CrawlerInterface {
 
	const URL = 'http://feeds.feedburner.com/cobaia/';
 
	public function __construct() {
		parent::__construct();
	}
 
	/**
	* Implements the getData method
	*/
	public function getData() {
		//request the url
		$this->request(self::URL);
		//filter by the tag item
		$news = pq('item');
		$result = array();
		//iterate by the results
		foreach ($news as $new) {
			//get the tag pubDate inside the DOM of new, and return the text
			$date = pq('pubDate', $new)->text();
			$date = date('Y-m-d', strtotime($date));
 
			$result[] = array('url' => pq('link', $new)->text(), //get the tag link inside the DOM of new, and return the text
							  'title' => pq('title', $new)->text(), //get the tag title inside the DOM of new, and return the text
							  'date' => $date);
		}
 
		return $result;
	}
 
 
}
?>

Well we implement the getData that make te request for the content, and search using the phpQuery the tags item, and inside each item we look for pubDate, link and title.

let’s test it:

1
2
3
4
5
6
7
8
9
10
11
< ?php
	//require the CrawlerFactory.php
	require 'CrawlerFactory.php';
 
	//call the Cobaia class and retrive the instance
	$crawler = CrawlerFactory::factory('Cobaia');
	//get the result
	$result = $crawler->getData();
	//show the result
	var_dump($result);
?>

Another example using the phpQuery selectors:

CrawlerPhpnet.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
< ?php
require 'CrawlerInterface.php';
 
class Phpnet extends Crawler implements CrawlerInterface {
 
	const URL = 'http://php.net';
 
	public function __construct() {
		parent::__construct();
	}
 
	/**
	* Implements the getData method
	*/
	public function getData() {
		//request the url
		$this->request(self::URL);
		$title = pq('h1.summary:first');
		return pq('a', $title)->text();
	}
 
 
}
?>

In this example we get the last title entry from the php.net website, using the CSS3 selector of phpQuery we can get the title:

let’s test:

1
2
3
4
5
6
7
8
9
10
11
< ?php
	//require the CrawlerFactory.php
	require 'CrawlerFactory.php';
 
	//call the Phpnet class and retrive the instance
	$crawler = CrawlerFactory::factory('Phpnet');
	//get the result
	$result = $crawler->getData();
	//show the result
	var_dump($result);
?>

This was an example of possibilites that we can do using the phpQuey, we made a simpĺe crawler, that get date from the some sites, we can do various things using the class phpQuery is very powerfull, and will help a lot your development.

I put the code in github, fell free to change the code.

ago 16 10

Some PHP functions to help your day

by Vinícius Krolow

isset()

The function isset determine if a variable is set and is not NULL, okay that I guess evebody knows.

But the isset accept multiple parameters:

1
2
3
4
5
< ?php
	$var1 = 'test';
	var_dump(isset($var1, $var2, $var3));
	//it will show FALSE
?>
1
2
3
4
5
6
7
< ?php
	$var1 = 'test';
	$var2 = 1;
	$var3 = 'test3';
	var_dump(isset($var1, $var2, $var3));
	//it will show TRUE
?>

key(), prev(), current(), next()

Iterate one array is a thing very common in PHP, but normally I saw in the PHP code just two types of iterate the foreach (the most common) and the for using the loops, but we have also other ways one is using the functions that we have since php4.

1
2
3
4
5
6
7
8
< ?php
	$work = array('simple', 'hard', 'meddium', 'easy', 'fastly');
	var_dump(current($work)); //simple
	var_dump(next($work)); //hard
	var_dump(next($work)); //meddium
	var_dump(prev($work)); //hard
	var_dump(end($work)); //fastly
?>

For itearate for example:

1
2
3
4
5
6
7
< ?php 
	$brands = array('ford', 'nissan', 'toyota', 'kia');
	while (!is_null($key = key($brands))) {
		var_dump($key, current($brands));
		next($brands);
	}
?>

Or the reverse iterate:

1
2
3
4
5
6
7
8
< ?php 
	$brands = array('ford', 'nissan', 'toyota', 'kia');
	end($brands);
	while (!is_null($key = key($brands))) {
		var_dump($key, current($brands));
		prev($brands);
	}
?>

String functions that you must knows:

strcasecmp(), strncasecmp(), with these functions you can compare string, and the second you also set the number of characters to compare for example:

1
2
3
4
5
6
7
8
9
10
11
< ?php
	$string1 = '1111abcdefg';
	$string2 = '1111testando';
 
	// Compare the first four characters
	//Returns < 0 if string1 is less than string2; > 0 if string1 is greater than string2, and 0 if they are equal.
	//!0 == 1 (true)
	//!1 == 0 (false)
	//!-1 == 0 (false)
	echo !strncasecmp($string1, $string2, 3); 
?>

substr_compare(), compare using pieces of string, and determine the index and the number of characters:

1
2
3
< ?php 
	echo substr_compare("abcde", "bc", 1, 3); // 1
?>

The strpos is really common but one function that do a simmilar job and I didn’t see so much in the code is the strstr, that function searches the haystack for a needle. But the difference between strpos is that function return the portion of the haystack that starts with the needle instead of the latter’s position:

1
2
3
4
< ?php
	$string = "linkhere http://terra.com.br";
	echo strstr($string, 'http://');
?>