Nikola Brežnjak blog - Tackling software development with a dose of humor
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Home
Daily Thoughts
Ionic
Stack Overflow
Books
About me
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Nikola Brežnjak blog - Tackling software development with a dose of humor
PHP, Quick tips

M is not for minutes in PHP date function

Ah, it was one of those days when you’re too smart for your own good and you don’t check the docs and falsely assume that m must definitely be minutes in the date function in PHP.

It should be

$dateNow = date("Y-m-d H:i:s");

and not H:m:i!

The offcial docs are clear, one just needs to read them 🙂

CodeProject, PHP

POST JSON Data With PHP cURL wrapper class

PHP biceps cURL 🙂

Following is the PHP cURL wrapper class which I use to make GET and POST requests. The examples are below. Disclamer:  be sure that you have permission to scrape and use the content you’re after.

This code is also available on GitHub at this link: https://github.com/Hitman666/PHPcURLWrapper

Class code and simple GET request

//CurlWrapper_static.php

class CurlWrapper {
    private static $useragents = array(            
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; WOW64; Trident/4.0; SLCC1)",
        "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14"
    );

	private static $cookiesFile = "curlCookies.txt";

    private static function getUserAgent() {
    	$rand = rand(0, count(self::$useragents) - 1);

    	return self::$useragents[$rand];
    }

    public static function SendRequest($url, $ref = "", $type = "GET", $postData = "", $headers = "", $proxy = "") {
        $useragent = self::getUserAgent();

        $ch = curl_init();
		curl_setopt($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_TIMEOUT,120);
		curl_setopt($ch, CURLOPT_USERAGENT, self::getUserAgent());

		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_AUTOREFERER, true);

		curl_setopt($ch, CURLOPT_COOKIEJAR, realpath(self::$cookiesFile)); 
		curl_setopt($ch, CURLOPT_COOKIEFILE, realpath(self::$cookiesFile));

		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        //options
        if ($ref != "") {
            curl_setopt($ch, CURLOPT_REFERER, $ref);
        }

		if ($proxy != "") {
			curl_setopt($ch, CURLOPT_PROXY, $proxy);
		}

		if ($type == "POST"){
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
		}

		if ($headers != ""){
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		}

        $result = curl_exec($ch);
		curl_close($ch);

		return $result;
	}
}

Simple GET request:

require("CurlWrapper_static.php");

$googleHTML = CurlWrapper::SendRequest('https://www.google.com');
echo $googleHTML;

If you’re a firm non-static lover here’s a “normal” class:

//CurlWrapper_nonStatic.php

class CurlWrapper{    
    private $_useragents = array(            
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; WOW64; Trident/4.0; SLCC1)",
        "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14"
    );

	private $_cookiesFile = "curlCookies.txt";

    private function getUserAgent(){
    	$rand = rand(0, count($this->_useragents));

    	return $useragents[$rand];
    }

    public function SendRequest($url, $ref = "", $type = "GET", $postData = "", $headers = "", $proxy = "") {
        $useragent = $this->getUserAgent();
        echo $useragent;

        $ch = curl_init();
		curl_setopt($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_TIMEOUT,120);
		curl_setopt($ch, CURLOPT_USERAGENT, $useragent);

		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_AUTOREFERER, true);

		curl_setopt($ch, CURLOPT_COOKIEJAR, realpath($this->_cookiesFile)); 
		curl_setopt($ch, CURLOPT_COOKIEFILE, realpath($this->_cookiesFile));

		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        //options
        if ($ref != "") {
            curl_setopt($ch, CURLOPT_REFERER, $ref);
        }

		if ($proxy != "") {
			curl_setopt($ch, CURLOPT_PROXY, $proxy);
		}

		if ($type == "POST"){
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
		}

		if ($headers != ""){
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		}

        $result = curl_exec($ch);
		curl_close($ch);

		return $result;
	}
}

How to use it with simple GET request:

require("CurlWrapper_nonStatic.php");

$curl = new CurlWrapper();
$googleHTML = $curl->SendRequest('https://www.google.com');
echo $googleHTML;

JSON POST request

Here’s an example of sending a JSON POST request to imaginitive URL ‘http://service.com/getData.json’ with some data array:

	require("CurlWrapper_static.php");

	$cookieSettingUrl = 'http://service.com/';
	$cookie = CurlWrapper::SendRequest($cookieSettingUrl);

	$data = array(
		"year" => 2014,
		"day" => 3,
                "month" => 4,
		"id" => 20
    );
	$postData = json_encode($data);

	$jsonUrl = 'http://service.com/getData.json';
	$headers = array('Accept: application/json','Content-Type: application/json');

	$resultsHTML = CurlWrapper::SendRequest($jsonUrl, $cookieSettingUrl, "POST", $postData, $headers);
	$resultsJson = json_decode($resultsHTML);
	var_dump($resultsJson);

Important to note is that you have to add proper $headers array, and that you json_encode your data array as shown when POSTing to a service which expects JSON data.

Cookies

The reason why I first used these two lines:

$cookieSettingUrl = 'http://service.com/';
$cookie = CurlWrapper::SendRequest($cookieSettingUrl);

is to set any cookies (and you will find that some services do this) that may be needed to be sent along with the request to ‘http://service.com/getData.json’. Cookies are set to ‘curlCookies.txt’ in the CurlWrapper_* class. You can change this to your liking, and you have to make sure that you set proper permissions for this file.

Hope this proves useful to someone.

PHP

Simple PHP XML parser using SimpleXML

Say you have a simple XML file books.xml  that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book>
		<author>
			<name>Nikola</name>
			<surname>Brežnjak</surname>
		</author>
		<title>Some awesome book title</title>
		<year>2014</year>
	</book>

	<book>
		<author>
			<name>Patrick</name>
			<surname>Rothfuss</surname>
		</author>
		<title>Doors of stone</title>
		<year>20xx</year>
	</book>
</books>

and you want to get all the names of the authors, you can use SimpleXML:

<?php
	$xml = simplexml_load_file("books.xml");
	var_dump($xml);

	$data = array();
	foreach ($xml as $book){
		$data[] = (string)$book->author->name;
	}

	var_dump($data);
?>

The output in this case will look like this:
PHPsimpleXMLoutput

CodeProject, PHP

Simple caching with Cache_Lite without having to install it through PEAR

Sooner or later everyone has to make use of some kind of caching of their content. Below is the simplest possible code demonstration on how to implement caching with Cache_Lite (download Cache_Lite standalone PHP class file which you can just include to your project without having to install it through PEAR):

require_once('Cache_Lite.php');
$cache = new Cache_Lite(	
  array(
    'cacheDir' => "cache/",
    'lifeTime' => 20 //seconds
  )
);

$req = "file.txt";
if($data = $cache->get($req)) {
  echo "Result from cache: " . $data;
}
else {
  $data = file_get_contents($req); // this is usually a DB call!
  $cache->save($data);
  echo "Result not from cache: " . $data;
}

So, first you require the class file, make a new instance by setting a caching directory and cache lifetime. For demonstration purposes I’m outputing the contents of file.txt but of course in a real use case scenario that would be some result of a database query or sth like that.

Simply, to get the data from cache (if it exists) you have to call the get() function on the Cache_Lite object, and to save it, well, use save() function and you’re all done.

CodeProject, PHP

Using prepared statements in PHP with MySqli

So, as most of you know PHP 5.5.x has deprecated the original MySQL extension, and instead we should be using  MySQLi or PDO_MySQL extensions. Here I will show you how to use MySQLi to query the database. I will cover the basic SELECT statement with and without prepared statements, and will show you the benefits of using mysqlnd driver.

For example purposes say we have a repository class where we keep our cars:

class CarRepository {
	private static $_host;
	private static $_database;
	private static $_user;
	private static $_password;
	private static $_mysqli;

	private static $_initialized = false;

    // this is a fix because static classes in php do not call contructor automatically
    //http://stackoverflow.com/questions/468642/is-it-possible-to-create-static-classes-in-php-like-in-c
    private static function initialize() {
        if (self::$_initialized)
            return;

        $credientials = CredentialsManager::GetCredentials();

        self::$_host = $credientials['host'];
        self::$_database = $credientials['database'];
        self::$_user = $credientials['user'];
        self::$_password = $credientials['pass'];        

        self::$_initialized = true;
    }

    private static function openConnection() {
        self::$_mysqli = new mysqli(self::$_host, self::$_user, self::$_password, self::$_database);
        if (self::$_mysqli->connect_errno) {
            echo "Failed to connect to MySQL: " . self::$_mysqli->connect_error;
            return false;
        }       

        return true;
    }

As you can see in the code the initialize() function is used because static classes in PHP don’t call contructor automatically. The CredentialsManager class may look like this:

class CredentialsManager {
    private static $_Host;
    private static $_Database;
    private static $_User;
    private static $_Pass;

    public static function GetCredentials() {
        CredentialsManager::GetLocalHostCredentials();

        return array(
            'host' => CredentialsManager::$_Host,
            'database' => CredentialsManager::$_Database,
            'user' => CredentialsManager::$_User,
            'pass' => CredentialsManager::$_Pass
        );    
    }

    private static function GetLocalHostCredentials() {
        CredentialsManager::$_Host = "localhost";
        CredentialsManager::$_Database = "database";
        CredentialsManager::$_User = "username";
        CredentialsManager::$_Pass = "password";
    }
}

The openConnection() function in the CarRepository class opens the connection to the database and stores it in the private $_mysqli variable. Note that this is the object oriented style of opening the connection, and that there is also a procedural style.

Finally, lets query the database for some data:

public static function GetCarOfTheDay() {
	self::initialize();

    if (self::openConnection()) {
    	$carObj = self::$_mysqli->query("SELECT * FROM cars WHERE car_of_the_day=true ORDER BY position LIMIT 1");

    	$car = self::makeObjects($carObj);

		return $car;
    }
    else
    	return false;
}

So, simply we just call the query method on the $_mysqli object with the SQL query and we get mysqli_result object:

object(mysqli_result)#3 (5) {
    ["current_field"]=> int(0) 
    ["field_count"]=> int(21) 
    ["lengths"]=> NULL 
    ["num_rows"]=> int(1) 
    ["type"]=> int(0)
}

I send this object into another function which then returns a Car object for me:

$car = self::makeObjects($carObj);

Lets keep it simple and say the makeObjects looks like this:

public static function makeObjects($carObj){
	require_once("Car.php");
	$cars = array();

	while ($row = $carObj->fetch_assoc()) {
		$car = new Car();

		$row = $carObj->fetch_assoc();

		$car->Id = $row["id"];
		$car->Make = $row["make"];
		$car->Year = $row["year"];

	}

 	if (count($cars) > 1)
 		return $cars;
 	else
 		return $cars[0];
}

Function returns only one Car object if there is only one or an array of Car objects if there are more results. Fetching more cars would look like this (basically the same call!):

public static function GetAllCars() {
	self::initialize();

    if (self::openConnection()) {
    	$carObjs = self::$_mysqli->query("SELECT * FROM cars");

    	$cars = self::makeObjects($carObjs);

		return $cars;
    }
    else
    	return false;
}

You can use queries like this when there are no parameters going into your SQL queries like the ones shown above, but what if you would like to query the database for a car by its id? Naturally, you would make a function like getCarById($id) with the $id as a parameter. Now, you may try to this along these lines:

public static function GetCarById($id) {
	self::initialize();

	if (self::openConnection()) {
		$carsObj = self::$_mysqli->query("SELECT * FROM cars WHERE id=" . $id);		
	}
	else 
		return false;
}

and though this would work, you would actually be exposing your self to a potential SQL injection attack. And sure, one could argue that you could escape the $id variable and whatnot, but that’s just not the way how it’s done these days. You can learn more about it on this post on StackOverflow, but basically what they say is that you should be using prepared statements.

The following code  shows how to query the database using prepared statements in mysqli (the function echoes the car’s make and year from the cars table):

public static function GetCarMakesById($id) {
	self::initialize();

	if (self::openConnection()) {
		$stmt = self::$_mysqli->prepare("SELECT make, year FROM cars WHERE id=?");

		$stmt->bind_param("i", $id);

		$stmt->execute();

		$stmt->bind_result($make, $year);

        $stmt->fetch();   

        printf("%s - %s\n", $make, $year);
	}
	else 
		return "oh noez";
}

So, here we put the query in the prepare() method of the mysqli object, and you may notice the ? instead of the actual parameter. That’s just the way how these prepared statements are written in mysqli. Then you tell it which parameter actually comes in place of ? and itself then makes sure it’s properly escaped, etc. The i in bind_param() method is for “integer”, s is for “string”, d is for “double”, b is for blob (read more about it here).

After that you have to call execute() and then bind_result() which binds/stores the result from the database query to variables set in it (in our case $make and $year) once you call the fetch() method.

Another example of fetching the data where we have more rows:

public static function GetCarMakesPerYear($year) {
	self::initialize();

	if (self::openConnection()) {
		$stmt = self::$_mysqli->prepare("SELECT make FROM cars WHERE year=?");

		$stmt->bind_param("i", $year);

		$stmt->execute();

		$stmt->bind_result($make);

        while ($stmt->fetch()) {
            printf("%s\n", $make);
        }
	}
	else 
		return false;
}

The code above would print out all the makes of a certain year. Now, up to this point all was great and I was pretty happy how things work, but then, I had to make a select like:

SELECT * FROM cars;

and now I was in trouble. After extensive googling I found out that I basically have two options:

  • use the get_result() function on the mysqli object or
  • list all the fields in the bind_result() and use fetch

At this point I immediately thought, now why would anyone not want to use get_result? [This would particularly help me because then I could just query the db with get_result() and just send that object to makeObjects() and thus using the same exact code – no duplication]

Right, so, the problem was that in order to use get_result() function on the mysqli object you would have to have mysqlnd driver installed (You can learn more on these few links). So, since I had PHP 5.3 and I tried updating with yum install php-mysqlnd I got into trouble. I even posted this question on StackOverflow. The solution I used in the end, as I outline it on SO, was to update PHP to 5.4 and force install php54-mysqlnd-5.4.17-1.ius.el6.x86_64 package.

In order to test if you have mysqlnd support you can run this code:

$mysqlnd = function_exists('mysqli_fetch_all');

if ($mysqlnd) {
    echo 'mysqlnd enabled!';
}
else {
	echo "nope";
}

Finally, with this all set I’m now able to use fetch_all() function like this:

public static function GetCarById($id){            
	self::initialize();

if (self::openConnection()) {
    $stmt = self::$_mysqli->prepare("SELECT * FROM car WHERE id=?");
    $stmt->bind_param("i", $id);

    $stmt->execute();

    $carObj = $stmt->get_result();

    $car = self::makeObjects($carObj);

    return $car;
}
else 
    return false;
}

To use the LIKE in prepared statements you have to “prepare” your variable before, like this:

$stmt = self::$_mysqli->prepare("SELECT * FROM car WHERE make LIKE ?");
$make .= '%';
$stmt->bind_param("s", $make);

Wohoo, happy coding!
Link to this article on CodeProject

CodeProject, PHP

Building a really simple PHP templating engine

Recently I had to make use of templates in PHP, and as a lot of people on StackOverflow ([1], [2]) suggested “you don’t need another templating engine like Smarty on top of PHP,  as PHP itself is a templating engine”.

So, I ended up making a simple function which looks like this:

function getTemplate($file, $variables = NULL){
    if (! is_null($variables))
    extract($variables);

    include(TEMPLATES_FOLDER . $file);	
}

TEMPLATES_FOLDER is a PHP constant which is defined in the config.php file like this:

if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');

define("TEMPLATES_FOLDER", ABSPATH . "templates/");

So, for example a template may look like this:

<!-- Navigation START -->
<div class="navigation">
	<div class="welcome">Hi, <?=$user;?></div>
	<div class="nav">
		<ul>
			<li><a href="home.php" class="<? echo (isset($currentHome) ? 'current' : '') ?>">Home</a></li>
	        <li><a href="members.php" class="<? echo (isset($currentMembers) ? 'current' : '')  ?>">Members</a></li>
		</ul>
	</div>

	<div class="clear"></div>
</div>
<!-- Navigation START -->

Here you can see the usage of ternary if operator:

echo (isset($currentHome) ? 'current' : '')

And a way to call this template from a home.php file would be:

<? getTemplate("navigation.php", array("user" => getUser(), "currentHome" => true) ); ?>

So the getTemplate() function loads the navigation.php file and passes it its variables “user” and “currentHome” which are then in the getTemplate() function extracted by using the extract() function and echoed out. The currentHome variable is set  when called from the home.php file so that a template “knows” to set the “current” class to that element.

Templating engines have their pros and cons, and since I didn’t need much leverage on the templating this proved to serve me just fine.

What do you use for your template management in PHP?
Link to this article on CodeProject

Recent posts

  • Discipline is also a talent
  • Play for the fun of it
  • The importance of failing
  • A fresh start
  • Perseverance

Categories

  • Android (3)
  • Books (114)
    • Programming (22)
  • CodeProject (35)
  • Daily Thoughts (77)
  • Go (3)
  • iOS (5)
  • JavaScript (127)
    • Angular (4)
    • Angular 2 (3)
    • Ionic (61)
    • Ionic2 (2)
    • Ionic3 (8)
    • MEAN (3)
    • NodeJS (27)
    • Phaser (1)
    • React (1)
    • Three.js (1)
    • Vue.js (2)
  • Leadership (1)
  • Meetups (8)
  • Miscellaneou$ (77)
    • Breaking News (8)
    • CodeSchool (2)
    • Hacker Games (3)
    • Pluralsight (7)
    • Projects (2)
    • Sublime Text (2)
  • PHP (6)
  • Quick tips (40)
  • Servers (8)
    • Heroku (1)
    • Linux (3)
  • Stack Overflow (81)
  • Unity3D (9)
  • Windows (8)
    • C# (2)
    • WPF (3)
  • Wordpress (2)

"There's no short-term solution for a long-term result." ~ Greg Plitt

"Everything around you that you call life was made up by people that were no smarter than you." ~ S. Jobs

"Hard work beats talent when talent doesn't work hard." ~ Tim Notke

© since 2016 - Nikola Brežnjak