Archive for the ‘PHP’ Category

Join files together into a single file and expand out

Thursday, March 11th, 2010

Again as with the previous post (simple calculator) this was another question to answer, which was fun to do.

“Write a class containing 2 functions. One function to merge 2 or more images into a single binary file. Write a counterpart function to this,which can extract the original files from the single binary, and write them out as single images, using their original filenames. Compression is not necessary, as the exercise is only designed to show an
understanding of using binary files with PHP, filesystem error handling, and planning a simple file format.”

Since we needed to have a simply file structure, so I decided to have a file structure of

Filename: <filename>
Size: <size in bytes>
<data>

where the filename, size in bytes and data (of the file itself) is filled in when the program runs.

So to start with I created a directory structure to pick up files from within one directory and place into another

/images
/newimages

and placed some images into the images directory.

To scan within a directory there is a iterator within PHP called DirectoryIterator which will do what it says on the tin, it will give you files within a directory and since being a iterator you can use a foreach to go through each file. Here is the syntax for DirectoryIterator to loop with a foreach (the $fileDirectory is the directory to scan and the $fileDetails is the files that are within the directory.

foreach (new DirectoryIterator($fileDirectory) as $fileDetails)

So what happens is that the program will loop through each file in the directory and open the single to write to, whilst looping through directory output the Filename to the single file and the Filesize, then read the actual file into a object to write to the single file within a binary format, and loop until no more files in that directory.

Then to un-single the file, I read the single file and find out the filename and filesize, open a file to write to in the new directory and read from the single file bits with the size of the filesize information from the single file, this was the actual file data, place this file data into the new file within the new directory. (kinder how tar works, builds all files into a single file from a directory and then expand then afterwards).

Here is the full code, it is small enough to hopefully follow.

<?php
  class imageBuilder 
  {
    /* read files into one file */
    /* file format 
      Filename: <filename>
      Size: <size in bytes>
      <data>
    */
    function readFiles($fileDirectory,$outputName)
    {
      $fHandle = fopen($outputName, "wb");
      if ($fHandle == false) throw new Exception("Error open file to write to");
      foreach (new DirectoryIterator($fileDirectory) as $fileDetails)
      {
	$filesize = filesize($fileDirectory."/".$fileDetails);
	if ($filesize > 0 && $fileDetails !="..")
	{
	  $rHandle = fopen($fileDirectory."/".$fileDetails, "rb");
	  if ($rHandle == false) throw new Exception("Error open file to read from");
	  $readInFile = fread($rHandle,$filesize);
	  if ($readInFile==false) throw new Exception("Error on reading file to read from");
	  fclose($rHandle);
	  if (fwrite($fHandle, "Filename: $fileDetails\n")==false) throw new Exception("Error writting data");
	  if (fwrite($fHandle, "Size : $filesize\n")==false) throw new Exception("Error writting data");
	  if (fwrite($fHandle,$readInFile)==false) throw new Exception("Error writting data");
	}
      }
      fclose($fHandle);
    }
 
    /* write files back out from the single file*/
    function writeFiles($fileDriectoryToWrite, $fileToReadFrom)
    {
      $rHandle = fopen($fileToReadFrom,"rb");
      if ($rHandle==false) throw new Exception("Error opening file to read");
      while (!feof($rHandle))
      {
	$filename = fgets($rHandle);
	$filename = trim(substr($filename, stripos($filename, ":")+1));
	if (strlen($filename) == 0) break;
	if ($filename == false) throw new Exception("Error reading the filename from file");
	$filesize = fgets($rHandle);
	if ($filesize ==false) throw new Exception("Error reading the filesize from the file");
	$filesize = trim(substr($filesize, stripos($filesize,":")+1));
	$readFileInfo = fread($rHandle, $filesize);
	if ($readFileInfo == false) throw new Exception("Error reading data from file to read from");
	$fHandle = fopen($fileDriectoryToWrite."/".$filename,"wb");
	if ($fHandle == false) throw new Exception("Error opening writing to file");
	if (fwrite($fHandle, $readFileInfo) == false) throw new Exception("Error writing to file");
	fclose($fHandle);
      }
      fclose($rHandle);
    }
  }
 
  $imageB = new imageBuilder();
  try {
    $imageB->readFiles("images","filetogether");
  }
  catch (Exception $ex)
  {
    echo "Error building the one file : $ex";
  }
 
  try {
    $imageB->writeFiles("newimages","filetogether");
  }
  catch (Exception $ex)
  {
    echo "Error writing files back out : $ex";
  }
 
?>

and you need to do is place some files within the /images directory and then run the program and it will create a single file called “filetogether” and also expand that file into the /newimages directory.

Simple calculator

Thursday, March 11th, 2010

Within a interview they requested me to do some exercises at home and here is the question that they posed.

“Create a simple stack-based calculator. This should be capable of performing addition, subtraction, multiplication and division. Example input would be: “2*(3+1)”. The result should be expressed as a numeric value, so the example should return 8. Usage of the eval() function, although amusing, is not allowed! This test is designed to show general programming skills, rather than an understanding of the programming platform; however the solution should be demonstrated using php as the language.”

So I decided to post on this site as well the design and program that I did come up with.

Since in maths you have to equate the ( .. ) first and then * , / , + , – so to start with I created a function that will pull out the brackets from the string input

    /* need to find the brackets and then equate the value and build outwards */
    public function equate()
    {
       // this is the string that was inputted when the class was created ( $this->calcstr;)
	$theStr = $this->calcstr;
 
	$bracketI = strrpos($theStr, "(");
	// there is a bracket
	while ($bracketI >=0)
	{
	  // find a bracket to match
	  $bracketEnd = strpos($theStr, ")", $bracketI);
	  if ($bracketEnd > 0)
	  {
	    // match then get the internal bracket value
	    $EqualMiddle = substr($theStr, $bracketI+1, ($bracketEnd-$bracketI)-1);
	    $calMiddle = $this->calculateTheString($EqualMiddle);
	    // rebuild the string without the bracket but with the value
	    $theStr = substr($theStr,0, $bracketI) . $calMiddle. substr($theStr, $bracketEnd+1);
	  }
	  else
	    throw new Exception("Bracket miss matched");
 
	  $bracketI = strrpos($theStr, "(");
	  if ($bracketI == false && $theStr[0] != "(") break;
	}
	return $this->calculateTheString($theStr);
    }

So what happens is that it will find the last occurrence of a bracket “(” and then find the corresponding “)” for that bracket, error is not found. Once found, it will then send to a function called “calculateTheString” that will actually calculate the value.

The calculateTheString function

 private function calculateTheString($theStr)
    {
	// look for * / + - in that order and then get the number each side to do the math
	$mathStr = array("*", "/", "+", "-");
	foreach ($mathStr as $maths)
	{
	  do 
	  {
	    // find each occurence of the math func
	    $mathI = strpos($theStr, $maths);
	    if ($mathI > 0)
	    {
	      // find the numeric values before and after the math func
	      try {
		$valueBefore = $this->getNumbericValue(substr($theStr, 0,$mathI), 0);
		$valueAfter =  $this->getNumbericValue(substr($theStr, $mathI+1), 1);
	      } catch (Exception $ex)
	      {
		echo "Error : $ex (String = $theStr)";
	      }
	      // do the math func
	      switch($maths)
	      {
		case "*" : $newV = $valueBefore * $valueAfter; break;
		case "/" : $newV = $valueBefore / $valueAfter; break;
		case "+" : $newV =$valueBefore + $valueAfter; break;
		case "-" : $newV =$valueBefore - $valueAfter;; break;
		default : $newV =0;
	      }
	      // rebuild string without the math func that is done
	      $theStr = substr($theStr,0,($mathI-strlen($valueBefore))) . ($newV) . substr($theStr,($mathI+strlen($valueAfter)+1));
	    }
	  } while ($mathI >0);
	}
	return $theStr;
    }

will loop through the math functions (*,/,+,-) in order of calculation, if it finds one of them it will equate what the value of that block of math is e.g.

4*2+1

it would equate the 4*2 and then rebuild the string to have the result within the next loop e.g.

8+1

so that when it gets to the + math function it will add 8 to 1.

To get the number values before and after the math functions (*,/,+,-) I created a function to pull out the values called “getNumbericValue”.. since the values will either be before or after the e.g. going backwards or forwards in the string, then you will need to either go in that direction. Once you have got the area within the string of the numeric values, then use the intval to convert into a integer value. The is_numeric makes sure that there is still a numeric value present.

/* $theStr = string to search, leftOrRight means going left or right in the string, 0 = left, 1=right*/
    private function getNumbericValue($theStr, $leftOrRight=1)
    {
	if (strlen($theStr) == 0) throw new Exception("No number value");
	if ($leftOrRight ==1) { $pos =0; 
	  $start = 0;
	}else 
	{
	  $pos = strlen($theStr)-1;
	  $start = strlen($theStr) -1;
	}
 	while (true)
	{
	  if (is_numeric($theStr[$pos]))
	  {
	    if ($leftOrRight == 0) $pos--; else $pos++;
	  }
	    else break;
	}
	// if just the number at the start
	if ($pos == -1) return intval($theStr);
	// if the start is greater than the end point, change over
	if ($start > $pos) { $tmp = $pos; $pos = $start; $start = $tmp;}
	return intval(substr($theStr,$start, $pos));
    }

To build all that together with

<?php
  class calc 
  {
    private $calcstr = "";
 
    function __construct($strIn)
    {
      $this->calcstr = $strIn;
    }
 
    public function setStr($strIn = "")
    {
      $this->calcstr = $strIn;
    }
 
    /* $theStr = string to search, leftOrRight means going left or right in the string, 0 = left, 1=right*/
    private function getNumbericValue($theStr, $leftOrRight=1)
    {
	if (strlen($theStr) == 0) throw new Exception("No number value");
	if ($leftOrRight ==1) { $pos =0; 
	  $start = 0;
	}else 
	{
	  $pos = strlen($theStr)-1;
	  $start = strlen($theStr) -1;
	}
 	while (true)
	{
	  if (is_numeric($theStr[$pos]))
	  {
	    if ($leftOrRight == 0) $pos--; else $pos++;
	  }
	    else break;
	}
	// if just the number at the start
	if ($pos == -1) return intval($theStr);
	// if the start is greater than the end point, change over
	if ($start > $pos) { $tmp = $pos; $pos = $start; $start = $tmp;}
	return intval(substr($theStr,$start, $pos));
    }
 
    private function calculateTheString($theStr)
    {
	// look for * / + - in that order and then get the number each side to do the math
	$mathStr = array("*", "/", "+", "-");
	foreach ($mathStr as $maths)
	{
	  do 
	  {
	    // find each occurence of the math func
	    $mathI = strpos($theStr, $maths);
	    if ($mathI > 0)
	    {
	      // find the numeric values before and after the math func
	      try {
		$valueBefore = $this->getNumbericValue(substr($theStr, 0,$mathI), 0);
		$valueAfter =  $this->getNumbericValue(substr($theStr, $mathI+1), 1);
	      } catch (Exception $ex)
	      {
		echo "Error : $ex (String = $theStr)";
	      }
	      // do the math func
	      switch($maths)
	      {
		case "*" : $newV = $valueBefore * $valueAfter; break;
		case "/" : $newV = $valueBefore / $valueAfter; break;
		case "+" : $newV =$valueBefore + $valueAfter; break;
		case "-" : $newV =$valueBefore - $valueAfter;; break;
		default : $newV =0;
	      }
	      // rebuild string without the math func that is done
	      $theStr = substr($theStr,0,($mathI-strlen($valueBefore))) . ($newV) . substr($theStr,($mathI+strlen($valueAfter)+1));
	    }
	  } while ($mathI >0);
	}
	return $theStr;
    }
 
    /* need to find the brackets and then equate the value and build outwards */
    public function equate()
    {
	$theStr = $this->calcstr;
 
	$bracketI = strrpos($theStr, "(");
	// there is a bracket
	while ($bracketI >=0)
	{
	  // find a bracket to match
	  $bracketEnd = strpos($theStr, ")", $bracketI);
	  if ($bracketEnd > 0)
	  {
	    // match then get the internal bracket value
	    $EqualMiddle = substr($theStr, $bracketI+1, ($bracketEnd-$bracketI)-1);
	    $calMiddle = $this->calculateTheString($EqualMiddle);
	    // rebuild the string without the bracket but with the value
	    $theStr = substr($theStr,0, $bracketI) . $calMiddle. substr($theStr, $bracketEnd+1);
	  }
	  else
	    throw new Exception("Bracket miss matched");
 
	  $bracketI = strrpos($theStr, "(");
	  if ($bracketI == false && $theStr[0] != "(") break;
	}
	return $this->calculateTheString($theStr);
    }
 
  }
 
  $theequal = "2*(3+1)";
  $thecalc = new calc($theequal);
  try {
    echo $thecalc->equate();
  } catch (Exception $err)
  {	
    echo $err;
  }
?>

and the output would be

8

I found it a interesting exercise :)

AJAX – setup and test

Monday, March 8th, 2010

AJAX is the way of communicating with a back end server without having to send the full information (you can of course) but for example you could just send a username check to see if it is available, but the main thing is that you do not send back a full page but only the part that you want to update.

With reference to the example of a username, you could just send the username and send back either yes or no response which saves allot of time and traffic from the client to the server (and makes the whole web page experience nicer).

All the AJAX is shorthand for “Asynchronous JAvascript and Xml”, asynchronous means that you can do something else whilst waiting for the response (put the kettle on and get a cup for the drink whilst the kettle is boiling) thus with javascript on the client web browser sends a request to a web page on the server with XML wrappings.

To get the basics lets start with the being

  // this function will return a XmlHttpRequest object that allows you to "talk" to the server.
  function GetXmlHttpObject()
  {
      // IE7+, FF, Chrome, Opera, Safari
      if (window.XMLHttpRequest) return new XMLHttpRequest;
 
      // IE6 , IE5
      if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
  }

the GetXmlHttpObject will return a object that will allow the javascript to talk to the backend server, the newer version is call a XMLHttpRequest whilst on older browsers it was part of the ActiveXObjects.

The next is to send a request to the backend server

    xmlHttpObject.onreadystatechange=callBackFunction;
    xmlHttpObject.open("GET", GetUrl, true);
    xmlHttpObject.send(null);

The onreadystatechange, will call a function (in javascript on the client browser) when the request alters from different states, the different states are

  • 1.open method invoked successful, open a connection with the server
  • 2.server responsed with a valid header response.
  • 3.server has sent some data, the response content is started to load.
  • 4.server has finished sending all of data

so from reading the states, you are really interested in state 4, because that will have the data (server response) that you are interested in for this.

The .open forms the request to the XmlHttpRequest object to call (”GET” in HTML) the server web site, the GetUrl is just a variable that well call a php page (”ajaxbackendcall.php”) which takes a parameter called name and returns a string with the name in reverse (shall include that source code later).

And then the .send will start the ready states to change and sends the request to the backend server, here is the function that is called on the state change

  function callBackFunction()
  {
    if (xmlHttpObject.readyState == 4)
      alert(xmlHttpObject.responseText);
  }

What is happening here, is that from the state stages I am waiting on ready state to equal 4 ( when the server has finished responding) and then output the response from the responseText which is filled from the AJAX call to the backend server.

That is mainly it, here is some full code for you to try out save this as “codingfriends.com.ajax.test.html”

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html3/strict.dtd">
<html>
<head>
<script type="text/javascript">
  // the xmlHttpRequest object
  var xmlHttpObject;
 
  // the ajax call 
  function getInnerText()
  {
    // get the name to send to the server backend page
    var namehere = document.getElementById("namehere");
 
    // request the xmlHttpObject 
    xmlHttpObject = GetXmlHttpObject();
 
    // if there is not xmlHttpRequest object being allowed to be created then the browser does not support it.
    if (xmlHttpObject==null)
    {
      alert("Browser does not support XmlHttp calls e.g. AJAX");
      return;
    }
 
    // fill in the request details, e.g. the url to call and also the query string inserted into the url
    var GetUrl = "ajaxbackendcall.php"+"?name="+namehere.value;
 
    // here is the call to the server.
    // to start with setup which function to call when a ready state on the XmlHttpRequest object has changed
    xmlHttpObject.onreadystatechange=callBackFunction;
    // request the html "GET" to obtain the url (e.g. the backend server page, dynmaic normally)
    xmlHttpObject.open("GET", GetUrl, true);
    // and then issue it
    xmlHttpObject.send(null);
  }
 
  // the function that is called once the XmlHttpRequest object state has changed
  /* the readyStates are 
    1 open method invoked successful, open a connection with the server
    2 server responsed with a valid header response.
    3 server has sent some data, the response content is started to load.
    4 server has finished sending all of data
  */
  // so we listen for readyState 4 when all finished
  // and output the response text into the div id innertextoutput
  function callBackFunction()
  {
    if (xmlHttpObject.readyState == 4)
      document.getElementById("innertextoutput").innerHTML=xmlHttpObject.responseText;
  }
 
  // this function will return a XmlHttpRequest object that allows you to "talk" to the server.
  function GetXmlHttpObject()
  {
      // IE7+, FF, Chrome, Opera, Safari
      if (window.XMLHttpRequest) return new XMLHttpRequest;
 
      // IE6 , IE5
      if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
  }
</script>
</head>
<body>
<a href="#" onclick="javascript:getInnerText()">click here to return text from a ajax call</a>
<br/>
Enter the name here <input id="namehere"/>
<br/>
<div id="innertextoutput"></div>
</body>
</html>

and then save this as the ajaxbackendcall.php file to call (in the same directory as the code above and also within a directory that has PHP plugin enable for that webserver be it apache or IIS.

<?php
    $name = $_GET['name'];
 
    // change the output to say something else, here I am just reversing the name
    if (strlen($name) > 0)
    {
      // have to insert something into it so that php does not make it into a array but a string
      $namereturn="0";
      $j = 0;
      for ($i = strlen($name)-1; $i >= 0; $i--)
      {
        $namereturn[$j++]=$name[$i];
      }
      echo "normal name {$name} and in reverse {$namereturn}";
    }
    else
      return "No name inputted";
?>

The output would be similar to the below. OUTPUT

click here to return text from a ajax call
Enter the name here

END OF OUTPUT

If you do not have a PHP webserver to test with, you can just alter the codingfriends.com.ajax.test.html code by altering the backend web page to call to this

var GetUrl = "nonephpbackend.html"

and create a page within the same directory as the codingfriends.com.ajax.test.html page and place something inside it like

hi there

Wordpress – plugin – hello world

Monday, February 15th, 2010

Wordpress is a blogging software that runs on a webserver, the great thing about wordpress is that you are able to extend the functions to create the pages/comments/archives etc on the blogging site. You are also able to create your own themes that will use the functions that you can create within that theme So lets it straight, a plugin for the wordpress is the way that you can extend the functional aspects of the whole site that is not dependent on the theme that you using (a theme is what you view on the web page the “style” (css) of the site for example).

There is two main directories within the wordpress directory structure to add in new themes (wp-content/themes) and the plugins (wp-content/plugins) this is where you place the code to extend the basic wordpress install.

In this example I going to extend the action get_header, if you save the code below into the directory wp-content/plugins/codingfriends_helloworld as codingfriends_helloworld.php

<?php
/*
Plugin Name: Coding friends hello world
Plugin URI: http://www.codingfriends.com/
Description: Outputs hello world
Version: 0.1
Author: Genux
Author URI: http://www.codingfriends.com
License: GPL2
*/
 
function codingfriends_helloworld()
{
  echo "hello world";
}
 
add_action('get_header', 'codingfriends_helloworld');
?>

once you have saved that file, then goto your wordpress admin page, on the left is the Plugins link, click on that and within there will be the “new” plugin called coding friends hello world, you just need to activate it and then hey presto it works. There will be “hello world” at the top of the wordpress installed pages within the main site (not the wp-admin part of the site).

What is happening is that you have created a function called codingfriends_hellworld, which outputs “hello world”, but the main part is the

add_action

this will add this function to a defined plugin action (to get a list of all of the actions (these happen within the core site), and filters (alter text within the site, e.g. pages that you add to the site, comments etc) you can use look here).

So when the action get_header is called within the main wordpress application, it will call your new function (codingfriends_helloworld).

There is tons of things that you can do with these, alter the comments when posted back to the site, pages etc, just look at the API list.

Blob to store data in mysql database

Tuesday, February 9th, 2010

To store data within a blob in a database can be a good thing at times because then you can just copy the database from one place to another and use the access rights on the database to restrict access to the “files” within the database.

There could be a few reasons why you want to store the data within a blob in the database, but here how the basics would work.

To start with you have to create a database and a table to store the data/file within the blob, of course if you have already created the database and/or the tables then alter as you think, but here is the basics.

  CREATE DATABASE phptestplace;
  CREATE TABLE storingData (id int NOT NULL auto_incremenet, lblob blob, PRIMARY KEY (id));

And then within a php file you can access the database and a file.

  $link = mysql_connect('localhost', 'username', 'userpassword');
  if (!$link) {
      die('Could not connect: ' . mysql_error());
  }
// alter to your database name
  mysql_select_db("phptestplace", $link);

and now access the file and read in file

  $filename = "filetoload.txt";
  $handle = fopen($filename, "r");
  $contents = fread($handle, filesize($filename));
  fclose($handle);
 
// to insert into the database you need to add in the slashes for characters like / \ etc.
  $contents = addslashes($contents);

to insert into the blob you just, change the table and table name to what may have called it.

  $sqlquery = "insert into storingData(largeblob) values ('$contents')";
  mysql_query($sqlquery) or die("ERROR");*/

to get the data back (I am calling back the last inserted value into the table)

// get the data into a result variable
  $return = mysql_query ("select lblob from storingData where id = (select max(id) from storingData)") or die("LLL");
// get the contents of the blob from the return variable (it returns a array of data) and the list takes out the data from a array each part at time.
  list($newcontents) = mysql_fetch_array($return);

and then store the data from the database pull into a file, I have called it newfile.txt, but it is up to you.

  $fp = fopen('NEWFILE.txt', 'w');
  fwrite($fp, $newcontents);
  fclose($fp);

Of course can do it via a web page, using a HTML FORM enctype=”multipart/form-data” within the form tag otherwise it may not work.

Polymorphism

Tuesday, February 2nd, 2010

Polymorphism means that you are deriving from a base class to create a new class, and the polymorphism is when you derive from the base class and implement a interface functions, so that any derived class will have to these functions implement so if you call a function that is defined by the interface to be present, you know it will be implement in some forum.

In php, there is a interface type, so we can define a basic Animal type to print is name, so that any animal that is derived from this interface will have to implement at least the print name function, here is the interface

interface Animal
{
  public function printName();
}

it is very similar to a class structure apart from there is no functional code, just the function definition. To then implement the interface Animal within a class, so that you will know that the printName() function will be implemented you use the “implements” keyword in the class definition as below.

class Cat implements Animal
{....

and then the class Cat will have to define the printName function as

  public function printName()
  {
     echo "Cat class\n";
  }

otherwise if you did not implement it there would be a error on the “compile time” as below.

Fatal error: Class Cat contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::printName)

here is a full code that will do a Cat and Dog class, then you can create a array of different derived Animals interfaces and then just call the printName and you know it will be present.

<?php
interface Animal
{
  public function printName();
}
 
class Cat implements Animal
{
      public function printName()
      {
	echo "Cat class\n";
      }
};
 
class Dog implements Animal 
{
      public function printName()
      {
	echo "Dog class\n";
      }
};
 
$animals = Array(
    new Cat(), new Dog()
    );
 
foreach ($animals as $a)
{
    $a->printName();
}
 
?>

and the output would be

Cat class
Dog class

Polymorphism is great, because you just know that certain functions will be implemented.

Regular expression – PHP

Friday, January 22nd, 2010

Regular expression is when you have a match condition and a string to search through. Here is a cheat sheet to download to view regular expressions syntax.

The regular matching method in php that I use is preg_match_all

int preg_match_all ( string pattern, string subject, array &matches [, int flags [, int offset]] )

which basically means that it will return a integer value of how many matches it has found within the subject text. The flags and offset are optional values.

Here is a example to pull out HTML A links within a text, A links start with <a and have some optional parameters e.g. href, title >text to display on the screen</a> (the closing tag. So in xml speak as such

<a[optional attributes]>value</a>

So the basics of searching for HTML A links within a string is to look for “” which then has the value and then the closing tag . So to put that in regular expression talk, to break it down we first search for the start <a followed by x amount of characters \s.* with a ending tag of <\/a> the “\” is there because the / is a condition statement for regular expression. And with this together it would look like

<a\s.*<\/a>

But because <\/a> happens twice in the string and either one can be the end point of the search since we are searching string values “\s.*” 0-x amount of them. \s means white space character “.” means any character that is not \n and “*” means 0 – more times of the previous check. So there is potential for a problem here we are not telling the regular expression to stop at the first < character and to this we use the [] to match some characters, the ^ in this context means any character not in this list about to come and "<" is the stopping character. So the full regular expression will be.

<a\s.[^<]*<\/a>

Here is the php code that will display all of the HTML A links from a string.

<?php
// here is a string with 2 a href links inside it and sounding text.
$matchAStr = "coding friends is my site :) <a href=\"http://www.codingfriends.com\">codingfriends.com</a> hi there.. " . 
	    " mountains are nice. <a href=\"http://www.norfolkhospice.org.uk/\">norfolkhospice.org.uk</a>" . 
	    " support the tapping house in Norfolk";
 
// the preg_match_all uses regular expression to match and pull out strings, $matches is the matches found.
 
$matched = preg_match_all("/<a\s.[^<]*<\/a>/",$matchAStr,$matches);
echo "There was $matched matche(s)\n";
 
echo "<ol>\n";
foreach($matches[0] as $url)
{
  echo "<li>".$url."</li>\n";
}
echo "</ol>\n";
?>
There was 2 matche(s)
<ol>
<li><a href="http://www.codingfriends.com">codingfriends.com</a></li>
<li><a href="http://www.norfolkhospice.org.uk/">norfolkhospice.org.uk</a></li>
</ol>

Wordsearch php – The words inserted into the grid

Monday, January 11th, 2010

The WordToSearchGrid class, it extends the grid class to add in the words to search for class.

The constructor from base class Grid creates the basic grid, I have added in a testing createGridRow() in this class to build just a empty grid (this is a great thing with class inheritance / extends etc, so that you can just re-write one aspect of the base class if you want it done a different way and it still works), and the output below is of the testing createGridRow() function so it makes it easier to see where the words was placed.

The direction of the words are like a compass directions, north, south, east and west and the north east, south east, north west and south west. Their are 8 directions in total that a word can take.

The getWords function gets the words to search for.

Here is a break down of the createSearchGrid function, which is the make aspect of placement of words.

    public function createSearchGrid()
    {
	// get the size of the grid
	$size = parent::returnSize();
 
	// loop thought the words to insert
	for ($i = 0; $i < count($this->_words); $i++)
	{

Loop thought the amount of words that are going to be inserted (tried to be)

	  $wordLen = strlen($this->_words[$i]);
	  // if the word is larger than the size of the grid, it cannot be inserted.
 
	  // NOTE : at present there is no intersection (crossing search words) shall do in the next version
 
	  if ($wordLen < $size) 
	  {

As NOTED in the code, there is no intersection at present, shall do this at a later stage, just the basics of insertion at present.

Also if the word to be inserted is longer in length than the actual grid then there is no point trying to insert it, because it will not fit.

	      //need to pick a direction and also a point on the grid.
	      // also need to try and place the word onto the grid x amount of times else break out.
	      $direction = rand(1,8);
	      $pointX = rand(1, $size);
	      $pointY = rand(1, $size);
 
	      // the remainder of the subtracting the points from the size of grid will basically say how much space is required
	      $space = $size - $wordLen;

Get a randomize direction, there are 8 directions and also randomized points to insert into the grid from 1 to the maximum size of the grid

	      // check against the direction and the size of the word against where it is on the poistion in the grid
	      // 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	      // from the points point of view.
 
	      $spaceY = $size - $pointY;
	      $spaceX = $size - $pointX;

Here is when the fun starts, the space X/Y left is basically how much space is left from the size of the grid to where the point X/Y are placed on the grid.

	      // if the direction is not east or west, and there is not enought space, move the insertion pointY difference
	      // north and south
	      if (!(($direction == 7) || ($direction == 3)))
	      {
		  if ($spaceY > $space) 
		      $pointY+= ($spaceY - $space);
	      }

If the direction is not going west or east then we are going north or south. The next question is, how much space is there to insert the word (we are always working in a north/west direction, but can move the word points around for south and east) and is the space left to insert the word greater than the space left required to insert the word.

E.g.. the size of the grid is 11 and the pointY = 2 and the word to insert is “merry” which has a word length of 5.
The space required ($space) = 11 – 5 which equals 6
The space left ($spaceY) = 11 – 2 which equals 9
and since we are always heading in a north/west direction as a default (if we are heading in any direction, e.g. sometimes it would be north or west or both).
then if the space left (9) is greater than the space required (6) which it is then increment the pointY (space left) the difference between the space left ($spaceY) and the space required ($space) which equals 3.

So from the equation this would be

if ( $spaceY (9) > $space (6) )
$pointY (2) increment by 3 which makes $pointY = 5 which is the length of the word (could just make it equal the length of the word, but I prefer the equation :) )

The below is the same as the north/south test, apart from east and west.

	      // if the direction is not north or south and there is not enought space, move the insertion pointX difference
	      // east and west.
	      if (!(($direction == 1) || ($direction == 5)))
	      {
		  if ($spaceX > $space)
		      $pointX+= ($spaceX - $space);
	      }
 
	      $this->insertIntoGrid($pointX, $pointY, $this->_words[$i], $direction);
	  }
	  else
	  {
	      // no need to tell the user to search for something that was not inserted
	      echo "Word ". $this->_words[$i] . " was too long for the wordsearch";
	      unset($this->_words[$i]);
	  }
	}
    }

The insertIntoGrid function, inserts the word that has a pointX and pointY coordinates and the direction.

    // insert into the grid at the positions x, y, the word to insert with the direction
    public function insertIntoGrid($pX, $pY, $word, $direction)
    {
	$wordLen = strlen($word);

Since we are based in north/west direction if the direction is south/east then correct the starting point to reflect the word direction.

	// move the starting point of the word to the correct place within the grid
	// the default is north and west, so will need to correct for south and east directions.
	if ($direction >=4 && $direction <=6) $pY-= ($wordLen-1);
	if ($direction >=2 && $direction <=4) $pX-= ($wordLen-1);
 
	// 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	// process each letter of the word and move the position to insert in the correct direction
	for ($i = 0; $i < $wordLen; $i++)
	{
	    parent::insertCharIntoGrid($pX, $pY, $word[$i]);
	    // move to the next grid position to insert the character
	    switch($direction)
	    {
	      case 1 : $pY--; break;
	      case 2 : $pY--; $pX++; break;
	      case 3 : $pX++; break;
	      case 4 : $pY++; $pX++; break;
	      case 5 : $pY++; break;
	      case 6 : $pY++; $pX--; break;
	      case 7 : $pX--; break;
	      case 8 : $pY--; $pX--; break;
	      default : break;
	    }
	}
    }

Here is the full class structure, and also a small demo. You will need to have the other classes in the same php file, the classes grid and the words.

class WordToSearchGrid extends Grid {
 
    private $_words;
 
    /* create a blank grid  - testing -- just need to comment out this function to create the real grid*/
    public function createGridRow()
    {
	$retArray = array();
	for ($i = 1; $i <= parent::returnSize(); $i++)
	{
	    $retArray[$i] = " ";
	}
	return array();
    }
 
    /* Gets the words to search for */
    public function getWords($wordsArray)
    {
	if (isset($wordsArray) && is_array($wordsArray))
	{
	  $this->_words = $wordsArray;
	}
    }
 
    // createSearchGrid, will insert the words onto a blank grid (for testing).
    // in random places and directions.
    public function createSearchGrid()
    {
	// get the size of the grid
	$size = parent::returnSize();
 
	// loop thought the words to insert
	for ($i = 0; $i < count($this->_words); $i++)
	{
	  $wordLen = strlen($this->_words[$i]);
	  // if the word is larger than the size of the grid, it cannot be inserted.
 
	  // NOTE : at present there is no intersection (crossing search words) shall do in the next version
 
	  if ($wordLen < $size) 
	  {
	      //need to pick a direction and also a point on the grid.
	      // also need to try and place the word onto the grid x amount of times else break out.
	      $direction = rand(1,8);
	      $pointX = rand(1, $size);
	      $pointY = rand(1, $size);
 
	      // the remainder of the subtracting the points from the size of grid will basically say how much space is required
	      $space = $size - $wordLen;
 
	      // check against the direction and the size of the word against where it is on the poistion in the grid
	      // 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	      // from the points point of view.
 
	      $spaceY = $size - $pointY;
	      $spaceX = $size - $pointX;
 
	      // if the direction is not east or west, and there is not enought space, move the insertion pointY difference
	      // north and south
	      if (!(($direction == 7) || ($direction == 3)))
	      {
		  if ($spaceY > $space) 
		      $pointY+= ($spaceY - $space);
	      }
 
	      // if the direction is not north or south and there is not enought space, move the insertion pointX difference
	      // east and west.
	      if (!(($direction == 1) || ($direction == 5)))
	      {
		  if ($spaceX > $space)
		      $pointX+= ($spaceX - $space);
	      }
 
	      $this->insertIntoGrid($pointX, $pointY, $this->_words[$i], $direction);
	  }
	  else
	  {
	      // no need to tell the user to search for something that was not inserted
	      echo "Word ". $this->_words[$i] . " was too long for the wordsearch";
	      unset($this->_words[$i]);
	  }
	}
    }
 
    // print out the words to search for that have been inserted into the grid
    public function printTheWordsToSearch()
    {
	foreach ($this->_words as $key => $value)
	{
	    echo "<br/>$key = $value";
	}
    }
 
    // insert into the grid at the positions x, y, the word to insert with the direction
    public function insertIntoGrid($pX, $pY, $word, $direction)
    {
	$wordLen = strlen($word);
 
	// move the starting point of the word to the correct place within the grid
	// the default is north and west, so will need to correct for south and east directions.
	if ($direction >=4 && $direction <=6) $pY-= ($wordLen-1);
	if ($direction >=2 && $direction <=4) $pX-= ($wordLen-1);
 
	// 1 = north , 2 = north east, 3 = east, 4 = south east, 5 = south, 6 = south west, 7 = west, 8= north west
	// process each letter of the word and move the position to insert in the correct direction
	for ($i = 0; $i < $wordLen; $i++)
	{
	    parent::insertCharIntoGrid($pX, $pY, $word[$i]);
	    // move to the next grid position to insert the character
	    switch($direction)
	    {
	      case 1 : $pY--; break;
	      case 2 : $pY--; $pX++; break;
	      case 3 : $pX++; break;
	      case 4 : $pY++; $pX++; break;
	      case 5 : $pY++; break;
	      case 6 : $pY++; $pX--; break;
	      case 7 : $pX--; break;
	      case 8 : $pY--; $pX--; break;
	      default : break;
	    }
	}
    }
}
 
 
$GridWords = new WordToSearchGrid(11);
 
$WordsToSearchFor = new Word("words.xml",3);
 
$GridWords->getWords($WordsToSearchFor->wordsArray());
 
$GridWords->createSearchGrid();
 
$GridWords->printOut();
 
$GridWords->printTheWordsToSearch();

Here is the output from the above, you may get something different since it is based on randomized numbers.

The grid
1 .. 1 = 2 = 3 = 4 = 5 = s 6 = 7 = 8 = 9 = 10 = 11 =
2 .. 1 = 2 = 3 = 4 = 5 = a 6 = 7 = 8 = 9 = 10 = 11 =
3 .. 1 = 2 = 3 = y 4 = 5 = w 6 = 7 = 8 = 9 = o 10 = 11 =
4 .. 1 = 2 = 3 = r 4 = 5 = 6 = 7 = 8 = 9 = 10 = l 11 =
5 .. 1 = 2 = 3 = r 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 = d
6 .. 1 = 2 = 3 = e 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
7 .. 1 = 2 = 3 = m 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
8 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
9 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
10 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
11 .. 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 =
 
0 = merry
1 = was
2 = old

Wordsearch – Word Class iterator

Thursday, January 7th, 2010

An iterator is when a object can be used within a foreach loop and each data item can be looped through, with a couple of other functions declared as well e.g. key, next because these functions allow the foreach loop to work. For example, at the start of the object you will need to have a position indicator (set normally at 0) and a object (array) to go through, I am using the word class from the word search project. From the php.net website there is a more details of a iterator.

The foreach loop basically starts the iterator from the starting point (rewind function) and then using the next function call to increment the internal object to its next point whilst making sure that it has not come to its end point (checking against the valid function).

Here is the code that I have used to demonstrate a iterator interface (interface example).

Please note, extending from the word class from a previous post.

class WordIterator extends Word implements Iterator {
    private $_position = 0;
    private $_wordsIterator;
 
    public function __construct($wordsOrFilename = "words.xml", $maxSearchNum = 5) {
        $this->_position = 0;
	$this->_wordsIterator = array();
 
	parent::__construct($wordsOrFilename, $maxSearchNum);
 
	$this->_wordsIterator = parent::wordsArray();
    }
 
    function rewind() {
        $this->_position = 0;
    }
 
    function current() {
        return $this->_wordsIterator[$this->_position];
    }
 
    function key() {
        return $this->_position;
    }
 
    function next() {
        ++$this->_position;
    }
 
    function valid() {
        return isset($this->_wordsIterator[$this->_position]);
    }
}
 
 
$WordIt = new WordIterator;
 
foreach($WordIt as $key => $value) {
    echo $key . " " . $value;
    echo "\n";
}

Output would be

0 merry
1 old 
2 sole 
3 was 
4 he

Extends class

Wednesday, January 6th, 2010

Extends a class within php, as described in more detail here. Basically is making a second class extended from the first class with either making amendments to some of the functions or adding some, this makes the second class the version 2 from the first class (version 1).

The extended class can still call the parent (version 1) class via the

parent::<function etc to call>

syntax, which basically means, calling the parent class to do something, for example the parent class may setup the variables of a array whilst the extended version 2 class may sort them into alphabetical order.

Here some code that may make more sense.

<?php
 
/* the base class, version 1 as such of a class */
class BaseClass {
    function HiFromMe()
    {
	echo "\nHi from the base class\n";
    }
 
    function BaseFunction()
    {
	echo "\nHi from base function\n";
    }
}
 
/* the extended class, this extends from the base class to make it a better (version 2) class */
class ExtendedClass extends BaseClass {
    function HiFromMe()
    {
	echo "\nHi from the extended class\n";
    }
 
    function CallBaseFunction()
    {
	echo "\nCalling base (parent) class";
	// need to put parent:: which means call the parent class
	parent::BaseFunction();
    }
}
 
$base = new BaseClass();
 
$base->HiFromMe();
$base->BaseFunction();
 
$extended = new ExtendedClass();
 
$extended->HiFromMe();
echo "\nYou can still call the base functions because you extended it";
$extended->BaseFunction();
echo "\nTo call from within a function";
$extended->CallBaseFunction();
?>
 
and the output would be... 
 
<pre lang="bash">
Hi from the base class
 
Hi from base function
 
Hi from the extended class
 
You can still call the base functions because you extended it
Hi from base function
 
To call from within a function
Calling base (parent) class
Hi from base function