Regular expression – PHP

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

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

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

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

Interfaces – the abstract class

An interface, as described further on the php.net website here, is basically a abstract class that defines a skeleton of what a class will have to at least implement, this allows for classes to implement a set skeleton and you will know what functions that class will have to implement.

The interface is just that, a skeleton of a base class. e.g. a interface could be a shape, and the classes that implement the interface called shape could be circle, square etc..because they will all have the basic functions for example, shape sides, colour etc.

Here is some php code, I always find looking over code easier to understand the basics of things.

<?php
 
/* this is a adstract class, e.g. any class that implements this class will have to implement all of the 
  skeleton functions that this class as defined 
 
  the abstract class is defined with the "interface" type */
 
interface Skeleton {
    public function printOutAWord($theWord);
 
    public function printOutAArray($theArray);
}
 
/* 
  this class, TheWorker, will actually "implement" the abstract class Skeleton, via the 
  implemets syntax  */
 
class TheWorker implements Skeleton {
    // these are the functions code that was defined by the abstract class.
    public function printOutAWord($theWord)
    {
	echo "\n$theWord\n";
    }
 
    public function printOutAArray($theArray)
    {
	echo "\n". print_r($theArray)."\n";
    }
}
 
$newWorker = new TheWorker();
 
$newWorker->printOutAWord("Printing out a word");
 
$newWorker->printOutAArray(array("Array","words","are","here"));
?>

And the output would be this

Printing out a word
Array
(
    [0] => Array
    [1] => words
    [2] => are
    [3] => here
)

Wordsearch php – Words to search for

As from the main project, wordsearch, here is the part that will either load the words from a xml file or from a input string on a web page. The grid class can be found here.

The basics of the word class, is to load a xml file (or via a user input string/s) and then generate words to search from the words that have either been loaded or inputted.

The word class can again be inherited so that each part can be re-done differently if there is another way to open a file etc.

I have included comments in the code, the __construct and __destruct are what happens when the class is created (via the “new” command) and destroyed respectively. Just a nice way to create the class/object and also clean up after itself.

The parameters that are passed to the __construct have default values, words.xml and 5, these can be over written when creating the class as shown in the code (instead of the maxSearchNum being 5 it is 3. But this gives more control over the construction of the class.

<?php
 
class Word {
    /* private section of the class word */
 
    private $_words;
 
    /* constructor for the word class 
       default action to load a xml file to gain 5 words
    */
 
    public function __construct($wordsOrFilename = "words.xml", $maxSearchNum = 5)
    {
	$this->_words = array();
 
	// if the filename is actually words from the input screen then just add in them instead
	if (is_array($wordsOrFilename)) 
	{
	  $_loadedWords = $wordsOrFilename;
	}
	else
	{
	  // load the file of words into a array
	  $_loadedWords = $this->loadWords($wordsOrFilename);
	}
	// create a array of words to be searched for, max number as above
	$this->_words = $this->searchableWords($_loadedWords, $maxSearchNum);
    }
 
    // unset the class words variable.
    public function __destruct()
    {
	unset($this->_words);
    }
 
    // load in the words file 
    public function loadWords($filename)
    {
	$xmlFileLoad = simplexml_load_file($filename);
	$returnWords = array();
	$i=0;
	foreach ($xmlFileLoad->word as $theword)
	{
	  // only the string, because otherwise it would be a simpleXMLObject
	  $returnWords[$i++] = (string)$theword;
	}
	return $returnWords;
    }
 
    // searchableWords will create a array of words to search for from the searchablewords parameter, with maximum number of searchs (maxsearch)
    public function searchableWords($searchableWords, $maxSearch)
    {
	$returnSearchWords = array();
	$numberSearchWords = count($searchableWords);
	// if the maxsearch value is greater or equal to the number of searchable words just fill in the return will all of the words
	if ($numberSearchWords <= $maxSearch)
	{
	    for ($i = 0; $i < $numberSearchWords; $i++)
	    {
	      $returnSearchWords[$i] = $searchableWords[$i];
	    }
	}
	else
	{
	  // randomly pick out words from the array of searchable words
	  for ($i = 0; $i < $maxSearch; $i++)
	  {
	    // re-index the array
	    $searchableWords = array_values($searchableWords);
	    // obtain a random index value
	    $searchWordNum = rand(0, count($searchableWords)-1);
	    // insert into the return value
	    $returnSearchWords[$i] = $searchableWords[$searchWordNum];
	    // delete the word from the array
	    unset($searchableWords[$searchWordNum]);
	  }
	}
	return $returnSearchWords;
    }
 
    public function wordsArray()
    {
	return $this->_words;
    }
 
    public function printOutWords()
    {
	prit_r($this->_words);
    }
};
 
 
$wordsToSearch = new Word("words.xml",3);
$wordsToSearch->printOutWords();
?>

and the output would be something like, of course since it is random generated, then could be the same words or different ones!!.

Array ( [0] => was [1] => sole [2] => old )

Wordsearch php – grid class

From the post on the projects page, wordsearch, here is a basic design of a grid class that can be used to link together with the other aspects of a wordsearch game. This will be able to create a basic grid and populate it with characters.

The reason why I created the createGridRow function was because this class could be inherited and thus alter any aspects of the class to suit the future needs.

The

$this->

within the code references the local variables of the class and not any other variables e.g. local to that function.

The

chr(rand(0,25) + 97);

means create a chr (character) from a random generated value within a range of 0 to 25 (26 letters in the English alphabet) and then add the value 97 to it, because the integer value of 97 – 125 are the ascii codes for a-z characters.

<?php
class Grid {
 
  /* private section of the class grid */
 
  // store the size and the grid
    private $_size = 0;
    private $_grid;
 
 
  /* the public section of the class grid */
 
    // construct the grid with a given size
    public function __construct($size=0) 
    { 
      // set the private variables
      $this->_size = $size; 
      $this->_grid = array();
      for ($i =1; $i <= $this->_size; $i++)
      {
	// create each row of the grid with the class function createGridRow
	$this->_grid[$i] = $this->createGridRow();
      }
    }
 
    // delete the grid 
    public function __destruct()
    {
      // clear up the grid, each line and then the whole object.
      for ($i = 1; $i <= $this->_size; $i++)
      {
	unset($this->_grid[$i]);
      }
      unset($this->_grid);
    }
 
    /* createGridRow, this can be inherited and thus altered to create any type of character in the grid */
    public function createGridRow()
    {
	$_grid_insert = array();
	for ($j = 1; $j <= $this->_size; $j++)
	{
	  $_grid_insert[$j] = chr(rand(0,25) + 97);
	}
	return $_grid_insert;
    }
 
    /* basic print out of a grid */
    public function printOut()
    {
      echo "The grid<br/>";
      for ($i = 1; $i <= $this->_size; $i++)
      {
	echo "$i .. ";
	for ($j = 1; $j <= $this->_size; $j++)
	{
	    echo " $j = ".$this->_grid[$i][$j];
	}
	echo "<br/>";
      }
    }
 
    /* return the size of the grid */
    public function returnSize()
    {
      return $this->_size;
    }
 
    /* insert a character into the grid at position X, Y and the character */
    public function insertCharIntoGrid($pX, $pY, $char)
    {
	$this->_grid[$pY][$pX] = $char;
    }
 
    /* return the grid reference */
    public function returnGrid()
    {
      return $this->_grid;
    }
}
$wordsearch_grid = new Grid(6);
$wordsearch_grid->printOut();
?>

The output of the code as above is

The grid
1 .. 1 = l 2 = l 3 = z 4 = m 5 = h 6 = m
2 .. 1 = u 2 = r 3 = z 4 = s 5 = k 6 = y
3 .. 1 = f 2 = k 3 = j 4 = n 5 = k 6 = p
4 .. 1 = h 2 = p 3 = x 4 = o 5 = c 6 = q
5 .. 1 = s 2 = s 3 = x 4 = r 5 = u 6 = v
6 .. 1 = r 2 = f 3 = g 4 = q 5 = s 6 = o