mschroeder 251 Bestower of Knowledge Team Colleague

My rule was actually tested and does work.

RewriteEngine On
RewriteRule ^get/([0-9]+)$ get.php?id=$1 [NC,L]

The NC makes it case insensitive and the L makes it stop processing once it has matched on that rule.

The second rule you posted in there will never be reached in the schema domain.com/get/123 as the first rule satisfies the match.

Perhaps your mod_rewrite module is not enabled?

If you're doing this simply to change the name of the file that is being saved it would be much more effective to send the correct headers with the file.

header('Pragma: public');
header('Cache-control: must-revalidate, post-check=0, pre-check=0');
header('Cache-control: private');
header('Expires: 0');
header('Content-Type: image/jpeg');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize('filename.jpg') );
header('Content-Disposition: attachment; filename=filename.jpg');
mschroeder 251 Bestower of Knowledge Team Colleague
mschroeder 251 Bestower of Knowledge Team Colleague

You need to use a .htaccess file (assuming you're using apache) and setup rewrite rules.

RewriteEngine On
RewriteRule ^get/([0-9]+)$ get.php?id=$1 [NC,L]

Something like that will probably get you what you want.

mschroeder 251 Bestower of Knowledge Team Colleague

Session garbage collecting is specific to how php handles sessions. It is independent of the storage mechanism.

There are three in particular that control the garbage collection you can see them all here: http://php.net/manual/en/session.configuration.php:
session.gc_probability
session.gc_divisor
session.gc_maxlifetime

There are a few caveats that affect how sessions work.

  1. Garbage collection is started with (gc_probability / gc_divisor) (default 1%) so it only has a 1% chance of running.
  2. Garbage collection runs on requests so if your server has little to no traffic don't expect your sessions to get cleaned up when they should expire.
  3. The gc_maxlifetime affects session life, but, again if the server is not running the garbage collector because of low traffic it will not be expiring sessions.

Essentially if you're storing your sessions in mysql, you can just empty the session table and forcefully log out all users. You could also delete all the files wherever your sessions are being stored and get the same result.

Suzie999 commented: Helpful advice +1
mschroeder 251 Bestower of Knowledge Team Colleague

This seems like it has two parts to me. To make dealing with the session data easier, implementing a custom session handler which stores the sessions in the database would be the first step.

http://www.php.net/manual/en/function.session-set-save-handler.php
http://www.nateklaiber.com/blog/2006/05/10/custom-php-session-handler
http://devzone.zend.com/article/141

Once you have that in place, you want to associate a logged in user id, the session id, and an ip address.

So say you have the following sql structure:

CREATE TABLE IF NOT EXISTS `sessions` (
  `id` varchar(32) NOT NULL,
  `access` int(11) NOT NULL COMMENT 'timestamp',
  `data` text NOT NULL COMMENT 'serialized array',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `users` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Username` varchar(320) NOT NULL,
  `Password` varchar(64) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `usersessions` (
  `UserId` int(11) NOT NULL,
  `SessionId` varchar(32) NOT NULL,
  `IpAddress` int(11) NOT NULL,
  PRIMARY KEY (`UserId`,`SessionId`,`IpAddress`),
  KEY `SessionId` (`SessionId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `usersessions`
  ADD CONSTRAINT `usersessions_ibfk_1` FOREIGN KEY (`UserId`) REFERENCES `users` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION,
  ADD CONSTRAINT `usersessions_ibfk_2` FOREIGN KEY (`SessionId`) REFERENCES `sessions` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION;

The session handler would take care of managing the data in the sessions table.

When you log a user in, the process would just be a series of quick checks. First, does the user have any records in the usersessions table, if no, then just log the user in …

mschroeder 251 Bestower of Knowledge Team Colleague

What exactly do you want an example of? The database structure, uploading files with php or storing/retrieving the data from the database?

mschroeder 251 Bestower of Knowledge Team Colleague

You have two options, you can store the images in mysql itself, which I would not recommend, or you can upload the images to your server and store the paths to the user's images in mysql.

When a user hits a profile, it would query the database for 1 or more photos of the user retrieve the path and then create a series of <img> tags with the correct paths.

mschroeder 251 Bestower of Knowledge Team Colleague

The eregi functions are deprecated in php 5.3 and since the php development team has officially announced the end of support for php 5.2.x you should update this function to use the preg_ functions instead of ereg.

http://www.php.net/manual/en/ref.pcre.php

mschroeder 251 Bestower of Knowledge Team Colleague

Speculating here, but you could possibly make it check the referrer. I'm not sure if window.open will pass a referrer though.

mschroeder 251 Bestower of Knowledge Team Colleague

It would be something you configured on the scanner. The ones I've used have both had software you could use, or their manuals had pages of barcodes you could scan to set the scanner up to do particular tasks.

mschroeder 251 Bestower of Knowledge Team Colleague

My experience with barcode scanners is fairly limited, but anything that is a standard usb scanner has always outputted whatever was scanned as if it was typed by a keyboard.

Any of the scanners I have used (only a few) were able to be configured to to automatically add a control character after the result of the scan, e.g. Enter, Tab, Space, New Line etc etc

What I did for one web interface was use JavaScript to put the focus in a field on the page automatically, when you scanned it was configured to send the Return/Enter character and submit the form. Validated the barcode saved the data and reloaded the page with the form and the focus once again on the input field.

mschroeder 251 Bestower of Knowledge Team Colleague

Using this line in your .htaccess fill will remove the type handler for the php files and they will be served by default as HTML to the user. So like text files, clicking the link will open the file instead of sending it to the php interpreter.

RemoveType .php .php3 .php4 .php5
mschroeder 251 Bestower of Knowledge Team Colleague

You have a few options:

1.) You can upload the files outside of the document root which will make them unaccessible via url. But, if you offer downloads you will have to do it via a php script.

2.) You can use a .htaccess file with a FileMatch directive to disable all access to .php files.

<FilesMatch "\.(php)$">
Order allow,deny
Deny from all
</FilesMatch>

http://httpd.apache.org/docs/current/mod/core.html#filesmatch

mschroeder 251 Bestower of Knowledge Team Colleague

The real question is, how much reading vs writing happens with your tree structure, with MPTT pulling data is very fast and you take a performance hit on the writes/updates as this requires touching a larger number of records. Where as adjacency takes its performance hit on read operations and is much faster with inserts/updates.

MPTT has no issues dealing with more than two children either. What is the requirement for your tree structure to be a binary tree (left & right children)? Your table as defined seems to be a mixture of adjacency and MPTT.

mschroeder 251 Bestower of Knowledge Team Colleague

@jkon

I believe the OP is using MPTT (Modified Preorder Tree Traversal).

sitepoint has a good example of this: http://articles.sitepoint.com/article/hierarchical-data-database

mschroeder 251 Bestower of Knowledge Team Colleague

I know this will probably be a more advanced response than what you are looking for but there are a lot of advantages to this kind of code in terms of re-usability. So I'm going to post this hoping it helps you as well as anyone else who needs to solve the same kind of problem.

<?php

/**
 * ExtensionFilterIterator Class
 * Used to filter a directory iterator by any number of extensions
 * 
 * @link http://www.php.net/manual/en/class.filteriterator.php
 */
class ExtensionFilterIterator extends FilterIterator
{
	/**
	 * Stores an array of extensions to filter on
	 * @var array
	 */
	protected $_extensions = array();
    
	
	/**
	 * Creates a class instance and sets extensions to filter on
	 * @param Iterator $iterator
	 * @param array|string $extension
	 */
	public function __construct( Iterator $iterator , $extension )
	{
		parent::__construct( $iterator );
		if( is_string( $extension ) ){
			$this->_extensions[] = $extension;
		}
		
		if( is_array( $extension ) ){
			$this->_extensions = $extension;
		}
    }
    
    /**
     * Implementation of abstract accept method
     * Determines if item is a file and also if the file has a valid extension
     * 
     *@see FilterIterator::accept()
     */
    public function accept()
    {
        $item = $this->getInnerIterator()->current();
		if( $item->isFile() && in_array( substr( $item->getFilename(), ( strrpos( $item->getFilename(), '.') + 1 ) ), $this->_extensions ) ){
			return true;
		}
        return false;
    }
}

Once you have the ExtensionFilterIterator defined in a file that you can include/require into your project its usage is simple.

//Defile the path to the image directory
$path = 'images/';

//Create a DirectoryIterator instance with the path …
mschroeder 251 Bestower of Knowledge Team Colleague

The above SQL is wrong.

The correct statement would be:

SELECT SUM(Price) Total FROM table_name

This aliases the result of SUM(Price) to the column Total for easier reference.
More info on aliasing columns: http://dev.mysql.com/doc/refman/5.0/en/select.html

mschroeder 251 Bestower of Knowledge Team Colleague

Look at the Zend PHP 5.3 Certification Study Guide. (http://www.zend.com/topics/PHP-5-3-Study-Guide-v1.pdf)

Covers a broad range of topics and they have some very good questions that really make you think about what you're seeing.

e.g. What is the output of this code?

$a = 1;
++$a;
$a *= $a;
echo $a--;
mschroeder 251 Bestower of Knowledge Team Colleague

So I've been messing with this problem a little bit more this evening.
UTF-8 has always intrigued me but I've never had an application I had to worry about it on.

I've been using the chart from http://www.utf8-chartable.de/unicode-utf8-table.pl to get UTF-8 characters to test.

$string = 'Թ';
echo 'Uppercase: '.mb_convert_case($string, MB_CASE_UPPER, "UTF-8").'<br />';
echo 'Lowercase: '.mb_convert_case($string, MB_CASE_LOWER, "UTF-8").'<br />';
echo 'Original: '.$string.'<br />';

Once my file was actually set to UTF-8 encoding, this started working like a charm.
Seems like the hardest problem will be determining the incoming encoding type and then converting that to UTF-8

mschroeder 251 Bestower of Knowledge Team Colleague

I really like Adobe Kuler
http://kuler.adobe.com/

mschroeder 251 Bestower of Knowledge Team Colleague

for ease of sql queries and such I would make a table called friends with only 3 fields: id, friend1, friend2 (although you could name it more appropriately)

anyways for each and every user/friend store their id in friend1 and their friend's id in friend2. this means that each time a friend is added you add 2 entries to the friends table.

The reason to do this is for simple SQL queries. when you load someone's profile you will only have to do a SELECT friend2 FROM friends WHERE friend1 = {user's ID} to get a full list of that users friends.

Actually to properly normalize and design this table, one would not have a separate `id` column. This simply limits the amount of data in the table and makes it possible to have duplicate friend relationships.

CREATE TABLE IF NOT EXISTS `friends` (
  `UserId` int(11) NOT NULL,
  `FriendId` int(11) NOT NULL,
  PRIMARY KEY (`UserId`,`FriendId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

As this demonstrates, drop the id column and make your primary key a composite of the Userid and FriendId columns. This prevents UserId 1 from having the same friend connection twice.

mschroeder 251 Bestower of Knowledge Team Colleague

Well both strtolower and strtoupper are not UTF-8 compatible but I believe you already knew this.

http://www.phpwact.org/php/i18n/utf-8 is a great resource for the compatability of utf-8 with the current string functions in php.

I get the same results as you when I put my own test together using a recommended internationalization test string (Iñtërnâtiônàlizætiøn).

<?php header('Content-Type: text/html; charset=utf-8'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
 
<body>
<?php
//header ('Content-type: text/html; charset=utf-8');
$string = 'Iñtërnâtiônàlizætiøn';

echo strtoupper($string).PHP_EOL;
echo strtolower($string).PHP_EOL;
echo mb_strtoupper($string).PHP_EOL;
echo mb_strtolower($string).PHP_EOL;
?>
</body>
</html>

It appears that strtoupper returns the string with the ASCII characters capitalized and the utf-8 characters untouched. However strtolower seems to corrupt the string.

IñTëRNâTIôNàLIZæTIøN
i�t�rn�ti�n�liz�ti�n
IñTëRNâTIôNàLIZæTIøN
i�t�rn�ti�n�liz�ti�n
mschroeder 251 Bestower of Knowledge Team Colleague

@anirban1087

I have attached a visual representation of what I gather reading your description.
From your earlier post I see you are trying to develop a storage solution for this.

I still think MPTT would be the way to store the hierarchical as illustrated in the second attachment I included. Once the data is stored in this fashion you can use the mechanism described in those links I provided to retrieve, insert and update your data with ease.

To handle the "logicl" hands, I would have a many-to-many join table where the member is joined to n members indicating the number of sponsored or logical hands that exist.

So 49400 has 2 physical hands (L & R) and has 3 logical hands.
The physical hands would be from selecting the direct child nodes, this would be true for all relationships. The logical hands would come from a separate table that maintained the logical relationship.

|MemberId | HandId   |
+---------+----------+
| 49400   | 119167   |
| 49400   | 119992   |
| 49400   | 119991   |
+---------+----------+

The description as to how you want to work with this data is rather vague so please elaborate if I'm way off base.

mschroeder 251 Bestower of Knowledge Team Colleague

http://php.net/manual/en/function.is-int.php

Examples should pretty much show you what you want. No sense in reiterating them here.

mschroeder 251 Bestower of Knowledge Team Colleague

How proficient are you with MySQL and PHP? There are usually two ways I see this solved. The easier to grasp of the two being recursion and the more complex but powerful would be using something like Modified Preorder Tree Traversal (MPTT).

I was not aware Oracle supported a native hierarchal data type will definitely keep that in mind.

http://articles.sitepoint.com/article/hierarchical-data-database
http://en.wikipedia.org/wiki/Tree_traversal
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

mschroeder 251 Bestower of Knowledge Team Colleague

Completely agree with vinayakgarg.

Packages like vBulletin have years and years of development by a team of developers.

But don't get discouraged. Put the time in and learn the tools you'll need and you'll be creating great applications before you know it. But, you have to learn the tools first.

mschroeder 251 Bestower of Knowledge Team Colleague

Are you setting the session id that is passed via the url before calling session_start on domain xyz?

<?php
if( isset($_GET['ssid'] ) ){
  session_id( $_GET['ssid'] );
}

session_start();

http://us3.php.net/manual/en/function.session-id.php

mschroeder 251 Bestower of Knowledge Team Colleague

If you visit domain abc.com you will get a session id. Session ids are stored via a cookie. You can not read cookies from another domain via php.

So when you visit xyz.com its going to look for a session id in a cookie for domain xyz.com it won't find one and it will create a new session.

If by multiple sites you're using sub1.domain.com and sub2.domain.com you can have it set the cookie for .domain.com and all subdomains will be able to access it.

mschroeder 251 Bestower of Knowledge Team Colleague

Check out this object oriented session handler: http://www.nateklaiber.com/blog/2006/05/10/custom-php-session-handler

Also this procedural session handler:
http://phpsecurity.org/code/ch08-2

The base64 encoding/decoding is superfluous because the data goes into a serialized array within the database.

mschroeder 251 Bestower of Knowledge Team Colleague

<?php must be on its own line.

Remove the comment Borzoi mentioned and add error_reporting(E_ALL); below the php tag. Like what I posted above.

mschroeder 251 Bestower of Knowledge Team Colleague

**Didn't see the code posted. :icon_redface:
Borzoi looks to have nailed it with the comment.

mschroeder 251 Bestower of Knowledge Team Colleague

add that line to the top of your index.php file.

http://www.php.net/manual/en/function.error-reporting.php

You probably have an error of some sort that is being suppressed currently.

mschroeder 251 Bestower of Knowledge Team Colleague

http://www.w3.org/TR/html401/struct/global.html#edef-HTML

It is the root element of any html document

mschroeder 251 Bestower of Knowledge Team Colleague

Is error_reporting turned on?

<?php
error_reporting(E_ALL);

//rest of file
...
mschroeder 251 Bestower of Knowledge Team Colleague

You can alleviate this problem by using a UUID or hashing the UUID for your activation key.
http://en.wikipedia.org/wiki/Universally_unique_identifier

There are several php modules that do this, but I've been using a pure PHP implementation with a lot of success
Class: http://www.shapeshifter.se/wp-content/uploads/2008/09/classuuid.phps
Usage: http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/

Check out the probability getting a duplicate key on the Wikipedia article. You basically have the same chance of getting hit by a meteorite as you do of creating a duplicate uuid for every 70 trillion generated.

mschroeder 251 Bestower of Knowledge Team Colleague

if the mysql server is on the same machine as your php code than localhost will most likely be your database server. If the mysql server is on a remote machine, you will need to use an ip or hostname and probably a port to connect.

In *most* hosting environments it will be localhost

mschroeder 251 Bestower of Knowledge Team Colleague

Wamp server is my personal preference on windows. Getting a local environment setup is the first step towards getting a better handle on things. All of those packages will provide, Apache, MySQL, and PHP and a handful of other varying apps. But those are the three you need to be able to work locally.

As far as learning php, there are tons and tons of great beginner tutorials. I suggest you google around. Get a solid understanding of the basics, variables, arrays, control statements, loops, etc. These are the integral building blocks to everything. Follow that up with learning how to create functions and deal with include files. If you have any specific questions start threads and show us what you're stuck on. There are a lot of very helpful people here who can guide you along.

mschroeder 251 Bestower of Knowledge Team Colleague

For starters unless $_POST is only a single character ord() will not work.
Secondly it only returns ascii values. http://www.asciitable.com/ I assume the characters you would be using are in the utf-8 spec.

There are some functions posted in the manual: http://php.net/manual/en/function.ord.php that seem to indicate utf-8 compatibility.

mschroeder 251 Bestower of Knowledge Team Colleague

Has nothing to do with being a jerk and that was not my intention. For everyone 1 person I see on these forums who actually make an effort, 5 more come here and simply say "give me ..." then never come back.

I'm more than happy to answer questions for you and point you in the right direction, just don't tell me you're to lazy to look it up, so I should just tell you the difference instead.

mschroeder 251 Bestower of Knowledge Team Colleague

Ahh so we should do the leg work for you...I see..
Yes master, right away master!

That won't get you anymore help from me...sorry

mschroeder 251 Bestower of Knowledge Team Colleague

Do you have a PHP environment installed locally?

I would suggest, WampServer, XAMPP or EasyPHP

mschroeder 251 Bestower of Knowledge Team Colleague

In my opinion you will probably have much more flexibility on a local machine than on a hosted solution. There are a few pain points I have encountered before though.

First, if your app is running a command line utility make sure it is available on all platforms or make your code capable of compensating and have it run different commands based on the os.

e.g. Your app uses `ls` to get a directory listing. This will fail on windows.

Second, php extensions have been a problem on windows. Outside of the common ones that ship with the installer, you're left to either find a pre-compiled one, build it from souce, or use pecl. All of those methods have been troublesome at one point or another. However the opposite is also true, you probably won't have as much flexibility on a hosted machine as the host will be in control of what is on and what is off.

As far as mailing goes, I would never advocate the use of mail() over smtp. It is trivial to use a php mailing library that connects to smtp without any issue. If you're using smtp sending mail from your localhost is a breeze. Just configure it to use ANY smtp gateway you have access to. Even the mail server on your hosting account, gmail etc.

mschroeder 251 Bestower of Knowledge Team Colleague

What is the use case for something like this?
It seems trivial to implement something like this within the function.

function someFucntion($a, $b, $c, $d = null)
{
  //Set $d to $b if $d is not set
  if( is_null($d) === true ){$d = $b;}
  ...
}

and if $d has to always be supplied you could just pass the value of $b to the function a second time.

function someFunction($a, $b, $c, $d)
{
  ...
}
//usage
$a = 2;
$b = 4;
$c = 5;
$value = someFunction($a, $b, $c, $b);
mschroeder 251 Bestower of Knowledge Team Colleague

Development platform aside, you want to start by understanding the domain you're trying to work in. In this case you would want to look at other booking systems and get an understanding of how the leisure center does business.

Once you have a good understanding of their processes, begin by modeling the domain. Define the entities and their attributes, as well as their relationship with each other.

e.g. You have a facility, which has rooms, maybe each room has a unique purpose or unique set of equipment. Maybe rooms can be combined via a foldable wall to create a compound room.

A facility could also have conditions for when it is available, such as monday - friday 8am - 5pm. So bookings should not be possible out of this window. Each room could have conditions such as a min/max number of users, certain membership level, etc.

A facility could also have employees, which have different levels of employment, manager, staff, trainer, etc. As well as also possibly having levels of membership such as bronze, silver, gold making it possible to reserve different sets of rooms or equipment.

etc. etc.

As your model becomes more refined your data will start to structure itself. So the next thing to do would be to define a data structure that works for your design. Once you have this designed and in place build the system to satisfy your modeling conditions.

This really lends itself to an object …

mschroeder 251 Bestower of Knowledge Team Colleague

A module is going to be an almost self-contained application made of models, views, controllers, components etc.

mschroeder 251 Bestower of Knowledge Team Colleague

It looks like someone created a function that essentially does what mkdir (http://php.net/manual/en/function.mkdir.php) already does with its recursive flag.

mschroeder 251 Bestower of Knowledge Team Colleague

I assume you're trying to provide a web frontend to some kind of form the user would fill out manually. In which case you could create a fillable pdf version of your form. This way it is visually identical to the form that would be filled out on paper.

Using php write the submitted form data to xfdf (http://partners.adobe.com/public/developer/en/xml/xfdf_2.0_draft.pdf) which is an xml format.

<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
  <ids original="a6a89dc100551c557b6f51bcb221c461" modified="a6a89dc100551c557b6f51bcb221c461"/>
  <f href=""/>
  <fields>
    <field name="Name">
      <value>John Doe</value>
    </field>
    <field name="Address">
      <value>123 Street</value>
    </field>
  </fields>
</xfdf>

Then, using an application like pdftk (http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/) fill the form with the xfdf data. You'll have a perfect 1 to 1 representation of your data in your visual form.

There are a few drawbacks to this though. Some hosts do not allow command line access which you will need to access Pdftk. Also some hosts do not have pdftk installed. Although I've been surprised by the number that do, mostly *nix hosts.

Once you have the generated pdf either attach the actual pdf to the email and send it or simply send the user a link to where they can open the pdf.

See Also: http://partners.adobe.com/public/developer/xml/index_arch.html

mschroeder 251 Bestower of Knowledge Team Colleague

Normally how I would approach this is make it work and then re-factor it into iterators etc. Since I've been so terribly busy the last few days I haven't had a chance to look at it again.

This should do what you wanted:

<?php

$printers = array(
	array('Printer_B', 'IDDHARMAHE'),
	array('Printer_B', 'IDSIRIKINE'),
	array('Printer_C', 'IDSUPRIY1'),
	array('Printer_A', 'IDSUSANTEN'),
	array('Printer_A', 'IDSUSANTEN'),
	array('Printer_B', 'IDSEPTIATR'),
);

class PrinterService
{
	public function getUsageByUniqueUser( array $printers )
	{
		$count = array();
		$uses = array();
		
		foreach( $printers as $use ){
			$uses[$use[0]][] = $use[1];
		}
		
		foreach( $uses as $key => $printer ){
			$printer = array_unique($printer);
			$count[$key] = count($printer);
		}
		
		return $count;
	}
}

$service = new PrinterService();
print_r($service->getUsageByUniqueUser($printers));
Array ( [Printer_B] => 3 [Printer_C] => 1 [Printer_A] => 1 )

Instead of the multiple loops there feels like there is a more efficient logic there, it just hasn't jumped out at me yet. Its also only single dimensional assuming that your array matches the array provided in structure. The keys are irrelevant.

mschroeder 251 Bestower of Knowledge Team Colleague

Depends on your definition of a "module" judging by what you've outlined and what ardav also outlined, I would say those are more like the objects that belong in the service level of your application.

Either way, there is no defined list of "must have" functionality. Design your application and decide what should or should not be part of the application. Or provide more of the concept of what you're trying to achieve and I'll be happy to provide you more insight.

PoisonedHeart commented: Thank you for your help! :) +2
mschroeder 251 Bestower of Knowledge Team Colleague

PrintFilter extends the FilterIterator class which is part of the SPL in php.
http://php.net/manual/en/book.spl.php
http://www.php.net/manual/en/class.filteriterator.php

The accept function needs to return true or false. True meaning that it is a valid item to iterate over, false meaning we can disregard it. How you determine it returns true or false is entirely up to you.

In my example, i'm using the 'value' parent::current() of the array item to do my comparison. You could also use parent::key() to get the array key.