Is there a reason you are not using DateTime and trying to use strtotime now?
strtotime is going to return a timestamp, not a DateTime object, so you are not going to be able to use $dteDiff as a DateInterval object like you posted originally.
Is there a reason you are not using DateTime and trying to use strtotime now?
strtotime is going to return a timestamp, not a DateTime object, so you are not going to be able to use $dteDiff as a DateInterval object like you posted originally.
$dteStart->diff($dteEnd);
returns an instance of DateInterval
If you want the hours from the DateInterval object you can use either of these formatting options, depending on the output you want and a call to DateInterval::format ( string $format )
H - Hours, numeric, at least 2 digits with leading 0 - 01, 02, 23
h - Hours, numeric - 1, 3, 23
echo $dteDiff->format('%h')
It sounds like you have a file with 10000+ lines in it, that you need to split into 50 line chunks and save to new files...
If the file is well over your php memory limit, reading the whole thing into memory will only cause you headaches.
I'd highly suggest using SplFileObject to iterate over the file line by line. This will give you a much smaller memory footprint.
Create a blank file also using SplFileObject, iterate over 50 lines of the original file, writing each line to the new blank file.
Keep a counter of how many lines you've read through. When you've reached 50, simply increment the blank file you're using.
I'll be happy to share code examples.
From a high level, your class is trying to accomplish to much in a single place. Check out the concept of SOLID (http://www.freeklijten.nl/home/2012/03/23/SOLID-The-S-is-for-Single-responsibility)
What you should ultimately end up with is a set of classes that allow you to work with emails in the most generic of ways. An Email object would represent an email and it's fields only. This should probably implement a standard interface so you can develop multiple email objects, e.g. PlainText, Html, Multi-part etc. These would extend a base class or implement some kind of inteface to ensure they have certain basic methods.
From there you would have an object that represents a mail server and is responsible for sending an Email Object. For example EmailTransport. Email transport might be setup to use different adapters that allow it to interact with multiple server types, sendmail, smtp, mock(for saving an email object to a file for testing), and mail(). This can be designed using the Adapter pattern.
For validation and filtering you would want two finds of objects, One that is able to deal with specific pieces of validation. Again you'd have multiple validators each with a single functionality. Filters would be setup the same way.
This is really high level and a lot to digest but these are some of the common things I see wrong with OOP code in the PHP world and I hope this helps to set you on the right path.
<?php
namespace Daniweb\Email;
interface EmailInterface
{
protected $to;
protected …
echo $array[79]->value;
Something like that should do the trick, obviously depends on what the variable that contains the array is named.
In the many years I've been developing with php, mailing is always a big pain point I see. As much as I like to advocate learning how to implement something yourself to have a better understanding of how things work and then looking for a more rigorously tested solution or building one, this is one of the few situations I'd say skip learning how to implement a mailing solution well. The specs are vast and complicated and if you're just trying to send emails it is easier to use a 3rd party library that will simplify all of it. If you simply rely on php's mail() function you will have nothing but headaches dealing with bounces and spam hits.
I really like the SwiftMailer (http://swiftmailer.org/) library. It is a great library with robust functionality that has seen a lot of recent attention thanks to the Symfony2 framework.
Zend_Mail is also a great package (http://framework.zend.com/manual/en/zend.mail.html) however I'm not sure how easy/difficult it would be to use it standalone. I'm sure there are tutorials that would explain what is necessary.
PHP Mailer is also one of the other big players. (http://phpmailer.worxware.com/)
$imagename = end(explode('/',$_POST['img']));
$img = mysql_real_escape_string($imagename);
Does not resolve the pass by reference issue given the ops original code.
$parts = explode('/',$_POST['img'])
$imagename = end( $parts );
$img = mysql_real_escape_string($imagename);
Should resolve the issue as the return of explode is not passed directly into another function call.
Can't really help you without seeing what the code before, on and after line 8 looks like.
Without seeing code I'm assuming your passing something like the return of explode() directly into another function. e.g. $foo = array_shift( explode( '.', $bar ) );
What kind of environment is your server running? If the host is using the suPHP module instead of the standard apache DSO module then your scripts execute as your user. So any files/directories may be writable, without having to be 777 etc.
A few points to consider.
CI documentation suggests using an underscore naming convention (Books_model) vs camelcasing like BooksModel. Models should also start with a capital letter and be followed only by lowercase letters.
Also your models should call the parent constructor.
//...
public function __construct() {
parent::__construct();
}
//...
Finally for a method to accept a post array as a method argument it means your method should look like:
public function fooBar( $post ){
//...
}
And would be used as:
$this->model->fooBar( $_POST ); //or the post object in CI
Why reinvent the wheel and try to create a code style guide from scratch when there are plenty of sensical, logical and well documented style guides out there already that are accepted and in use in lots of projects?
All you'll do with such a non-standard design is create a barrier that if you ever need someone to work on your code they'll spend more time trying to figure out the style than what it is they're tasked to do.
Since I just wrote this code answering your first question:
<?php
//Create an instance of now
//This is used to determine the current month and also to calculate the first and last day of the month
$now = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) );
//Create a DateTime representation of the first day of the current month based off of "now"
$start = new DateTime( $now->format('m/01/Y'), new DateTimeZone( 'America/New_York' ) );
//Create a DateTime representation of the last day of the current month based off of "now"
$end = new DateTime( $now->format('m/t/Y'), new DateTimeZone( 'America/New_York' ) );
//Define our interval (1 Day)
$interval = new DateInterval('P1D');
//Setup a DatePeriod instance to iterate between the start and end date by the interval
$period = new DatePeriod( $start, $interval, $end );
//Iterate over the DatePeriod instance
foreach( $period as $date ){
//Make sure the day displayed is greater than or equal to today
//Make sure the day displayed is NOT sunday.
if( $date >= $now && $date->format('w') != 0 ){
echo $date->format( 'l, Y-m-d H:i:s' ).PHP_EOL;
}
}
Saturday, 2011-11-12 00:00:00
Monday, 2011-11-14 00:00:00
Tuesday, 2011-11-15 00:00:00
Wednesday, 2011-11-16 00:00:00
Thursday, 2011-11-17 00:00:00
Friday, 2011-11-18 00:00:00
Saturday, 2011-11-19 00:00:00
Monday, 2011-11-21 00:00:00
Tuesday, 2011-11-22 00:00:00
Wednesday, 2011-11-23 00:00:00
Thursday, 2011-11-24 00:00:00
Friday, 2011-11-25 00:00:00
Saturday, 2011-11-26 00:00:00
Monday, 2011-11-28 00:00:00
Tuesday, 2011-11-29 00:00:00
This is easily adapted to answer your second question as well:
//Iterate over the DatePeriod instance
foreach( $period as $date ){
//Make sure the day displayed is ONLY …
This is why ajax and php are ill suited for a real-time chat solution. Because it has to make a new request every n seconds which means you're hitting the system fresh every time since php does not really maintain state between requests.
You would really want to look at Comet
http://en.wikipedia.org/wiki/Comet_(programming)
http://ajaxian.com/archives/comet-with-php
Or, implement some form of long-polling
http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/
die() ends your script execution. It is the same thing as exit(). So when your script hits the line die("go shawdy it's your database");
it exits and never executes the rest fo the script. Replace the die call with echo 'go shawdy it's your database';
and do the same for the other two in your function.
If you have installed the SQL Server driver from Microsoft than you need to use the sqlsrv_* functions as demonstrated here: http://social.technet.microsoft.com/wiki/contents/articles/accessing-sql-server-databases-from-php.aspx More specifically these functions http://php.net/manual/en/book.sqlsrv.php
Hashing is not the same thing as encryption. Your examples are all hashing.
If you need to be able to encrypt and decrypt the data than check out the php documentation for the mcrypt library.
http://php.net/manual/en/book.mcrypt.php
Good thing you resurrected a 2 year old thread...
To simply answer your question, the idea of a hash is to be a one way algorithm. The only way you could "decrypt" a hash would be to generate hashes until your found a match.
If you want to encrypt and decrypt then you want to use encryption, not hashing.
In the future please don't revive a thread this old.
vlowe,
[edit]
Err, I misread that initially
[/edit]
The PHP DateTime library would be my preferred method of doing what you want.
<?php
//Only need to specify parameters if your timezone is not set.
$now = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) ); //1319061332 or 10/19/2011 @ 4:55pm
//If your timezone is set in php.ini
//$now = new DateTime(); //1319061332 or 10/19/2011 @ 4:55pm
$timestamp = $now->getTimestamp(); //1319061332
//Minus 24 hours
$past24hrs = $now->sub( new DateInterval( 'P24H' ) );
$timestamp = $past24hrs->getTimestamp();
//Minus 1 week
$past1week = $now->sub( new DateInterval( 'P1W' ) );
$timestamp = $past1week->getTimestamp();
//Minus 30 days
$past30days = $now->sub( new DateInterval( 'P30D' ) );
$timestamp = $past30days->getTimestamp();
http://www.php.net/manual/en/class.datetime.php
http://www.php.net/manual/en/class.datetimezone.php
http://www.php.net/manual/en/class.dateinterval.php
[edit]
If you need a timestamp instead in milliseconds simply multiply the returned timestamps by 1000
[/edit]
To my understanding hmac variations are substantially less prone to collisions than the standard hash functions.
I know this is not directly related to your question, but have you considered using bcrypt for your passwords? Assuming your environment is 5.3+
http://us2.php.net/crypt
http://yorickpeterse.com/articles/use-bcrypt-fool/
http://phpmaster.com/why-you-should-use-bcrypt-to-hash-stored-passwords/
http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords
You are correct, this would need to be done with an .htaccess file.
Essentially taking www.example.com/#### and mapping it to example.com/page.php?id=####
There are lots of examples and this has been covered quite a bit on these forums.
http://www.php.net/manual/en/language.types.array.php
Your array keys are not included within quotes and there are not constants defined for username and passuser.
If you spent even a fraction of a minute looking at their HTML you'd notice an ajax link like this:
http://tastykitchen.com/recipes/wp-content/plugins/wp-recipes/ajax.php
If you use Firefox, Chrome or Safari, and opened the developer tools/firebug, and adjusted the servings you'd see that the site is using that to make an ajax request. Which then returns a full block of html that is replaced on the site.
Although that is not useful, what you will notice is the /plugins/wp-recipe/ part of that url.
Simply googled for "wp-recipe plugin" and got http://wordpress.org/extend/plugins/wp-recipes/
SImply download the plugin and review the actual PHP source code and you should have a great place to start from.
PHP is notoriously bad with UTF-8 characters. The only reasonable way I think you would accomplish this would be using the multi-byte functions. http://www.php.net/manual/en/ref.mbstring.php
$str = č;
if( mb_strpos( $_POST['tekst'], $str ) !== FALSE ) {
echo 'Found String';
} else {
echo 'No String';
}
I haven't tested this, but it should handle multi-byte characters better than the standard functions, however you don't have anywhere near the variety of functions to work with.
Because on line 62 - 65 when you catch the error, you do nothing to stop the execution of your script.
The query issue is because you are not passing the submitted account id into your query. You do on line 57, but not on line 69. Can you explain why you have two separate queries here?
I did read the entire thread and took the time to read through the ops code and provide a detailed response. You may have provided some php assistance :icon_rolleyes: but you still made the statement as well as another poster that the op should drop php validation in favor of javascript. The problem with this, is that eventually someone else well come across this thread and read that post and think "this is a good idea, i should remove my server-side validation in lieu of javascript!" and then their application will be terribly vulnerable. The posts I quoted are TERRIBLE advice, and I stand by that.
if( isset($_POST) && !empty($_POST) ){
exit();
}
Seriously this code is of no use. Just delete it and use javascript.
Just Use Javascript Validation and submit its value to the modify_data.php , make a connection in modify_data.php file and retrieve value from previous page using post method . Build a select query on this this page using retrieved values and display data .
This is TERRIBLE advice. Validation should never be done just on the client-side. All it takes is disabling javascript to be able to submit any data you want to the form. Or simply making a post/get request with something like curl.
Make it validate server-side (PHP) first, than worry about javascript validation as this benefits the user and prevents the need to submit the form for trivial issues.
First, have you tried turning error_reporting on? Error reporting is often disabled in environments. Just add error_reporting(E_ALL | E_STRICT);
after your <?php tags in your files. This will ensure you are actually seeing EVERY php error even the notices.
Note: line numbers are relevant to your posted code.
Second, line 28 - 31 of modify_data.php If that query doesn't return any results, it will show your message but continue running your code after that. http://php.net/manual/en/function.exit.php - Just one way to terminate execution.
Third, the query on line 33 appears as though it will fetch all of the data in your db since there is no where condition to limit it.
Fourth, …
1. For starters, anyone who has been around any form of serious web hosting environment will quickly tell you that there is NO such thing as unlimited hosting. There are no unlimited hard drives and there are no unlimited bandwidth connections. At some point there is a limit. Unlimited hosts may be getting better with the proliferation of massive hard drives and fast connections but there will always be a limit somewhere.
These shops tend to target smaller setups who have very small resource footprints and that is fine, but as soon as the resources grow to some, often unwritten, soft limitation you will have problems. This also tends to lead to a lot of overselling. Again if the resources are there it is not a big deal, until hundreds of accounts on the same server start trying to use the same chunk of unlimited bandwidth.
If you value the quality of your service and intend to have your site/service grow to a sizable level then do yourself a favor and steer clear of the allure of unlimited hosting. If you're just using it to get your feet wet and get off the ground it could be a cheap way to get started. You get what you pay for.
2. Video processing is going to require memory and processor resources. These are probably the most expensive and limited resources in a server. If your site sees any kind of steady traffic, you will probably quickly outgrow a …
$_FILES["file"]["type"] is supplied by the browser and is not checked by php for accuracy. You can overcome this by using something like the Fileinfo extension to actually check the file's mime type (http://www.php.net/manual/en/book.fileinfo.php)
You could drastically simplify the way that code reads by supplying an array of file types and then checking if the provided is in that array. e.g:
$allowed = array('image/gif','image/jpeg','image/pjpeg','application/pdf','application/msword','application/vnd.ms-excel');
if ( in_array($_FILES["file"]["type"], $allowed) && $_FILES["file"]["size"] < 20000000 )
{...}
Also if you're going to match by the mime you should consider normalizing the value that is provided. At the minimum make it's case consistent e.g. $type = strtolower($_FILES["file"]["type"]);
While I don't really understand why you got down voted, I will make an assumption it has to do with the lack of effort on your part.
If I was going to approach this, I would probably be looking at the php DOM extension (http://www.php.net/manual/en/book.dom.php).
Using an xPath query (http://www.php.net/manual/en/class.domxpath.php) to return all of my rows <tr></tr>
Then iterate over the collection of rows and checking if each elements nodeName (http://www.php.net/manual/en/class.domnode.php) property is equal to 'th'. If it is I would capture the nodeValue into an array. e.g. $attributes[$element->nodeValue].
Then to get it's value I would use the DOMNode::nextSibling property to get the next adjacent node which should be a td, so check its nodeName is equal to 'td' and then capture its nodeValue as the value of the previous node.
<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("filename.html");
// OR
//$doc->loadHTML("<html><body>Test<br></body></html>");
$xpath = new DOMXpath( $doc );
$elements = $xpath->query("//tr");
$attributes = array();
//Loop over every row object
foreach( $elements as $row ){
//Look over each cell in each row
foreach( $row as $cell ){
//We only care about TH cells so we only look for those specifically
if( strtoupper($cell->nodeName) == 'TH' ){
//If we find a TH cell then check if we have an adjacent TD cell.
if( strtoupper($cell->nextSibling->nodeName == 'TD' ){
//Create an array item using the TH's value as the key and the TD's value as the value. e.g. $attributes['Beds'] = 7
$attributes[$cell->nodeValue] = $cell->nextSibling->nodeValue;
}
}
} …
Some really good information on the subject and a hashing framework I see mentioned a lot.
Hashing is a one-way algorithm it can not be run in reverse.
Encryption is a two-way algorithm where a string and be encrypted and then decrypted.
md5 and sha1 can't be decrypted, but what those sites do, is maintain giant databases of common lookups. So if you make your password 'password' the md5 will always be '5f4dcc3b5aa765d61d8327deb882cf99' which means you can store that and you know that the hash always (minus collisions) matches password.
With hashes it is recommended to always salt the hash with additional random characters that is unique to your site. So if your salt is "!@#$VSA!@#adjk_48ashkj345" no matter how weak someones password is, by default it will be as strong as the salt.
e.g. A user's password of "password" is now "!@#$VSA!@#adjk_48ashkj345password!@#$VSA!@#adjk_48ashkj345" before it gets hashed. This prevents the hashes from being easily matched if your db is compromised, but does nothing if your site is exploited from the frontend where an attacker throws common works at your login fields. This is where rate limits and failed login checks come into play.
This is also a place where it is suggested to make logging in as slow as possible by doing thousands if not hundreds of thousands of hash calculations so you become a much less viable target to attack with automation.
If your hosting company is telling you their version of php does not support the mysqli extension then you should quickly find a new host. This would indicate to me either they are still running php 4, php 5 was release in july 2004, or they are to stubborn/lazy to enable what I would consider a standard php extension at this point, it is included with PHP 5 by default.
Mysqli provides many benefits over the mysql extension and they are not equals in any way. That is of course unless your host is also running a very old version of mysql as well (e.g. < 4.1). This considering 5.0, 5.1, 5.5 are all stable releases and 5.6 is well on it's way to becoming the next stable release.
Mysql is not actively developed, only minor maintenance releases. Mysqli is actively developed, recommended by MySQL as the preferred development extension, supports character sets, prepared statements, stored procedures, and multiple statements just for starters. It also supports the additional features and options in MySQL 4.1+, which the mysql extension does not.
There probably isn't a reason to actually delete records.
On the query you use to pull the comments you should add an ORDER BY clause that sorts them by the date they were added to the database (assuming you have a column for this) and then add a LIMIT clause (http://dev.mysql.com/doc/refman/5.1/en/select.html#id848826) so that only the most recent 10 results are shown.
Depends, session_start needs to be called before any output occurs or you'll get an error.
If your header include contains everything that would be between the header tags on the page, what is creating the container html? If your code looks like the following and you put the session start in the header include, it will error out, as the html is being sent to the browser before the session starts.
<html>
<head>
<?php include('header'); ?>
</head>
<body>
</body>
</html>
If the quantity ALWAYS has a , after it you can just take the chunk that is before the comma.
$item = '1,';
$item = substr($item, 0, -1);
echo $item; //1
You could also use str_replace to replace all occurrences of commas.
$item = '1,';
$item = str_replace(',', '', $item);
echo $item; //1
I'm not sure if I follow, but i'll take a shot at it.
Assuming $id from your query result is the ID-QUANTITY value, then you would pass $id as the second parameter of explode. The explode function would "explode" it apart at the dash (the first parameter) and you'd be left with an array, with two values.
$id = $result[0];
$quantity = $result[1];
If your string is always going to be in the format of ID-QUANTITY explode() would be faster and removes the need to use a regular expression.
<?php
$value = '1234-57';
$result = explode('-', $value);
echo $result[0].PHP_EOL; //1234
echo $result[1].PHP_EOL; //57
@chrishea
I have a development server where projects get subdomains configured as virtual hosts all other unmatched subdomains resolve to a single catch-all vhost. I don't think it is terribly uncommon just depends on the usage.
@tcollins
If you call <?php phpinfo(); ?>
from that file and look though the results for HTTP_HOST and it's value, you will probably see that the HTTP_HOST is test.domain.com or fail.domain.com, not just the subdomain portion.
Having the value in a hidden input field would be no different than the user selecting it from a drop-down where it is also visible in the source.
If you inspect the source of most web forms you're going to commonly find the use of hidden input fields. This is why filtering/validating input and escaping your output is so important.
If you want to keep the flow of your application at it is now, when the user clicks on the "Rate this Cigar" button and the cigar id is passed to the second page via a GET value e.g. ?CigarId=####
Then on the second page, if that get value is present, swap out the dropdown for the text field with the information and add in a hidden field with the same name as your drop-down.
When the form is posted it will process the form and the $_POST array will contain $_POST just as if it had been selected in the drop-down.
Assuming DateAdded is a Date or DateTime column in mysql.
SELECT COUNT(CigarID) AS ReviewCount FROM reviews_cigar WHERE $UserID = UserID AND $CigarID = CigarID AND WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= DateAdded
This should find any rows that have been added within the last 30 days of the DateAdded column.
**You may not want to use the COUNT() like I did because it will always return 1 row even when the count is 0.**
Unless you are benchmarking your code and load testing it for these kind of slow downs while you're developing, you're really not going to gain much by adding caching for the sake of adding caching. Caching is part of a scaling plan, and you can't tell where your code needs to scale until you know where you code fails and why.
The functionality you described is exactly what every dynamic database driven piece of code does. These slides might be of interest http://www.slideshare.net/JustinCarmony/effectice-caching-w-php-caching. Although the slides talk about memcache specifically the concepts they cover are relevant to all forms of cache storage.
-veledrom
I'm not sure I really understand the utility in caching the way you have described it. How have you arrived at the conclusion the database will slow down or give up if you don't use caching?
Sounds to me like you're trying to over optimize your code before you see where the code is going to bottleneck in the first place.
-veledrom
My suggestion to you, if you want to learn how to code well then you should be looking at well coded examples.
Symfony's File Cache (Many others in their package as well):
http://www.symfony-project.org/api/1_4/sfFileCache
Examples:
http://snippets.symfony-project.org/snippet/110
http://snippets.symfony-project.org/snippet/99
Zend Cache
http://framework.zend.com/manual/en/zend.cache.html
Code:
http://framework.zend.com/svn/framework/standard/branches/release-1.11/library/Zend/Cache.php
http://framework.zend.com/svn/framework/standard/branches/release-1.11/library/Zend/Cache/
CakePHP Cache
http://api.cakephp.org/class/cache
You'll see they are all very different but generally similar to one another. I would use these to try and put something of your own together as they'll illustrate lots of best practices and be well documented.
-ardav
Caching is kind of an open ended question. In my experiences the places where you think you need cache are usually not the places that benchmark poorly. Rule of thumb would be to cache external resources, e.g. if you're displaying daniweb's rss feed you wouldn't use file_get_contents, simplexml, dom, etc. to parse it every time a page loads you'd call that only if your local cache didn't exist and since you're caching that you might as well cache the rendered results before their displayed as they won't be changing either. Then you're doing almost no actual work to display that remote feed until the cache is expired, say every hour or two would be practical.
Some areas that I've also seen improved with caching would be large static objects. Like a site wide ACL. Where unless you're making changes to the acl …
I have used LiquidWeb and recommended to it many people for everything for shared, vps, dedicated, virtualization etc etc. In years of service I have never personally experienced a LiquidWeb outage.
If you check out WHT they have great reviews and used to be very active members of that forum.
Their support is top notch including 24/7 phone support. Pick up the phone, dial the number, talk to a real person in the states, get your problem solved. They go above and beyond for their customers and absolutely get what you pay for.
Cache expiration time entirely depends upon what is being cached. Without a particular use case there isn't really a "standard".
This is not caching. You're actually causing your script to do more work when it tries to serve from cache than when you're just generating the content dynamically.
The way caching should work, is when your script runs, it attempts to load a cache, via unique identifier (key, hash, filename, etc). When that cache request fails, because it is expired or it does not exist, then it proceeds to execute the code that will be saved into the cache, saves to the cache and displays what it generated.
This is hopefully just to give you an idea of what you might expect, if you want a more appropriate OOP solution, you'd probably want a Cache Interface that multiple cache adapters (file, db, mongo, memcache, etc) can implement so you have a consistent api. Perhaps even all tucked away behind a cache factory that handles creating the different cache instances based on a supplied adapter.
<?php
class Cache
{
protected $_key;
public function __construct( array $settings = array() )
{
//Do something with your settings
//Set maximum lifetime?
//Set directory path?
}
public function load( $key )
{
$this->_key = $key;
if( $this->isValid( $key ) )
{
$cache = file_get_content('some/path/to/some/file.cache');
return $cache
}
return false;
}
public function save( $cacheable )
{
//saves the generated content somewhere
//maybe check for object and serialize automatically (setting?)
}
public function isValid( $key )
{
//Validate the cache exists and is not expired etc.
//return true or false
}
public function expire( …
A tree structure is probably the wrong way to go about this. The data structure you describe would be more of a graph. Where each node can have 1:n connections to additional nodes. A tree structure is really best suite for parent-child kind of relationships.
http://en.wikipedia.org/wiki/Graph_(data_structure) has some general information on graph data structures and also provides some information on ways to represent your nodes in a graph as well as some common graph traversal algorithms.
Once you have solved your traversal across the graph you will be left with a resultant that can be represented as a doubly linked list (http://en.wikipedia.org/wiki/Doubly-linked_list) which will provide you with a bi directional set of nodes you iterate across. PHP's SPL actually has a data structure for doubly-linked lists already which is why I mention this.