mschroeder 251 Bestower of Knowledge Team Colleague

There is little that can be avoided of mixing html with your php in this instance however, I think the alternative control structures make for a nicer read than having your block of html encased in a single echo statement.

If you want to remove your php even more from your html, HEREDOC and NOWDOC (php 5.3 +) make this very easy with a little sprintf/printf usage.

There really isn't a right or wrong in this case, except your original example, but that was corrected by jtreminio.

<?php for( $i = 0; $i <= 10; $i++ ): ?>
	<tr>
		<td>
			<input name='rate<?php echo $i; ?>' id='rate<?php echo $i; ?>' type='text' onkeyup='integeronly(this)' >
		</td>
		<td>
			<input name='qty<?php echo $i; ?>' id='qty<?php echo $i; ?>' type='text' onkeyup='integeronly(this)' >
		</td>
		<td>
			<input name='amt<?php echo $i; ?>' id='amt<?php echo $i; ?>' type='text' readonly='readonly'>
		</td>
	</tr>
<?php endfor; ?>

If you want to take the chance you can use the shorttag echo, but ymmv:

<?php for( $i = 0; $i <= 10; $i++ ): ?>
	<tr>
		<td>
			<input name='rate<?=$i?>' id='rate<?=$i?>' type='text' onkeyup='integeronly(this)' >
		</td>
		<td>
			<input name='qty<?=$i?>' id='qty<?=$i?>' type='text' onkeyup='integeronly(this)' >
		</td>
		<td>
			<input name='amt<?=$i?>' id='amt<?=$i?>' type='text' readonly='readonly'>
		</td>
	</tr>
<?php endfor; ?>

You could also use HEREDOC with the sprintf functions, *BUT* you must escape the '$' placeholder. This will work with php < 5.3.

<?php
$html = <<<HTML
<tr>
	<td>
		<input name='rate%1\$s' id='rate%1\$s' type='text' onkeyup='integeronly(this)' >
	</td>
	<td>
		<input name='qty%1\$s' id='qty%1\$s' type='text' onkeyup='integeronly(this)' >
	</td>
	<td>
		<input name='amt%1\$s' id='amt%1\$s' …
mschroeder 251 Bestower of Knowledge Team Colleague

-phper

The problem I have with timestamps mostly has to do with the limited range they are available for, 1970 - 2038 approximately. If you were to try to store a date 30 years from today, say for a 30year mortgage, you will exhaust the 32bit integer timestamp.

Mysql's datetime and date data types do not suffer from this. It is also just as easy to do a range calculation with mysql's datetime columns.

e.g.

SELECT * FROM table WHERE table.`date` BETWEEN NOW() AND NOW() + INTERVAL 30 YEAR

Downside with that query would be the inability for mysql to cache its results because of the use of NOW(). However, if that is an issue it can be remedied by using the php DateTime class instead of the time() and date() functions, which does not suffer from the same range as the unix timestamp.

<?php
//Current DateTime
$now = new DateTime();
$start = $now->format( 'Y-m-d H:i:s' );

//add() is php 5.3.0 functionality
$now->add( new DateInterval('P30Y') );
//For php < 5.3.0
//$now->modify( '+30 year' );

$end = $now->format( 'Y-m-d H:i:s' );

$query = sprintf( 'SELECT * FROM table WHERE table.`date` BETWEEN "%s" AND "%s"', $start, $end );
echo $query; 
//SELECT * FROM table WHERE table.`date` BETWEEN "2011-02-22 20:20:52" AND "2041-02-22 20:20:52"
mschroeder 251 Bestower of Knowledge Team Colleague

Personally I prefer to store dates using the mysql date or datetime format, usually the later, but it is a personal preference.

You'll often see a unix timestamp in an int column, a mysql timestamp cplumn, and even sometimes a date stored as a string, which is the only one I would say is unacceptable and should be avoided.

Just however you choose to handle your dates, stick with it, don't mix and match date types throughout the application.

mschroeder 251 Bestower of Knowledge Team Colleague

You have basically finished the script, with the exception of two things.
You need to call the function, and your SQL statement should be looking for any delete_date values that are less than or equal to the current time. If you leave it as >= you will be deleting all articles that are set to expire in the future.

I'm not sure how your dates are stored in your database, but $current_date is unused in your function, and NOW() will only work if the delete_date column is a date/datetime/timestamp etc. (http://dev.mysql.com/doc/refman/5.0/en/datetime.html)

Also just a note, in files that are purely php, it is good practice to drop the closing ?>. This prevents any issues with whitespace after the closing tag.

<?php

function delete_expired() {
    $current_date = date("m.d.y"); 
    $sql = "DELETE FROM cms_table WHERE delete_date <= NOW()";
    $res = mysql_query($sql) or die(mysql_error());
}

delete_expired();
drewpark88 commented: Helped me a Bunch!! : ) +2
mschroeder 251 Bestower of Knowledge Team Colleague

Instead of hard deleting them would it not be easier and more effective to just limit the display of them by the "delete_date" parameter?

So when displaying posts only display posts where delete_date < NOW()?

Then you have no time priority to physically remove the items from your database and could have a database "clean-up" routine that can be run manually whenever you are logged in, or maybe runs anytime a new post is made so you don't need a cron script etc to do it?

drewpark88 commented: Awesome! +2
mschroeder 251 Bestower of Knowledge Team Colleague

Whats the reasoning behind hard deleting the row in the first place?

mschroeder 251 Bestower of Knowledge Team Colleague

Be careful with the getmxrr function, only since 5.3.0 has it been available on windows. If you know the environment you're writing the script for this won't be a problem, but if you're writing a script for others to deploy this is a limitation you will want to work around.

There is a good thread here: http://www.daniweb.com/forums/thread141944.html about this very topic. The solution could probably benefit from a little updating but its a solid concept.

mschroeder 251 Bestower of Knowledge Team Colleague

You could serve up an alternative image in its place via .htaccess but you can't force a page that displays your image to redirect to your website.

mschroeder 251 Bestower of Knowledge Team Colleague

Foreign keys are only relevant when the database tables are InnoDB. MyISAM does not support foreign key relationships in any way.

If you are using InnoDB you absolutely should be using the FK constraints for ON UPDATE and ON DELETE. These allow you to enforce your business rules on your data structure without having to implement the checks in your code.

e.g.
If you were to delete a cigar record, any table that contained additional information and referenced the cigar table primary key you could have those tables setup to cascade the delete, and remove the record in any linked table.

For modeling your database I highly suggest checking out MySQL Workbench (http://wb.mysql.com/) you can design the entire database in a graphical manner including the foreign key relationships etc and you can than export the sql for creating the database.

Also I would suggest adopting a solid set of naming conventions for your database. It will really make your life easier in the long run when everything follows the same conventions. Personally I use a set of conventions that are a slightly modified version of http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx

mschroeder 251 Bestower of Knowledge Team Colleague

It looks like only POST values get sent to php://input.
I reworked the function so it gets it's values from the $_SERVER variable.

<?php
function getRealGet()
{
	$pairs = explode( '&', $_SERVER['QUERY_STRING'] );
	$vars = array();
	foreach ($pairs as $pair) {
		$nv = explode("=", $pair);
		$name = urldecode($nv[0]);
		$value = urldecode($nv[1]);
		$vars[$name] = $value;
	}
	return $vars;
}

var_dump( getRealGet() );
OmniX commented: nice code example +4
mschroeder 251 Bestower of Knowledge Team Colleague

You can extrapolate from the function posted here: http://www.php.net/manual/en/language.variables.external.php#94607

mschroeder 251 Bestower of Knowledge Team Colleague

http://us3.php.net/variables.external

Explains why those periods are converted to underscores.
Through the comments there are also other characters that are mentioned that appear to be converted as well.

OmniX commented: useful link, thanks. +4
mschroeder 251 Bestower of Knowledge Team Colleague

I don't think there is really a best practice for handling variables. It really depends on the scope requirements of the variables.

If you prefer to work with many individual variables than continue to use $var1, $var2, etc etc.
If you don't like having so many loose variables, you could create a single array (single or multiple dimensions) that contains all the values.

e.g.

<?php

$variable = array(
  'page' => array(
    'title' => 'Page Title',
    'width' => 960,
  ),
  'form' => array(
    'field1' => 'value',
    'field2' => 37,
    'field3' => true,
  ),
);

If you use the array you can access everything down using: echo $variable['page']['title']; You also could slug all the variables into an object if you prefer the object notation of object->variable;

$obj = new stdClass();
$obj->page = new stdClass();
$obj->page->title = 'Page Title';
$obj->page->width = 960;

Personally I don't see much value in using objects as just empty stores like that.

Beyond the way you use the variables, you have to consider persistence. $var = 4; is only available within its local scope and must be passed into functions/objects etc. This is also only persisted for the current request.

Sessions allow you to persist volatile data over multiple requests while the use maintains their session. $_SESSION['var'] = 4; => index.php => go.php => xyz.php echo $_SESSION['var']; //4 Sessions are also global and can be accessed anywhere at anytime. But if the user loses their association with the session or closes the browser …

fuston05 commented: Very helpful, and knowledgable! +2
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

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

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

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

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

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

<?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

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

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

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

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.

mschroeder 251 Bestower of Knowledge Team Colleague

Yes, if you're not filtering it for a specific value.

In the foreach loop, you can test $key or $value for anything you want to compile the counts etc.

mschroeder 251 Bestower of Knowledge Team Colleague

Well i'm going to assume you're using at least PHP 5, so look at this idea and lets see if we can't craft something that will speedup your results:

<?php

//Multidimensional array of printers.
//This can be ANY depth.
$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'),
);

//PrinterFilter class to filter our iterator and ONLY return values that start with Printer_
class PrinterFilter extends FilterIterator
{
	public function accept()
	{
		//Only accept values that start with Printer_
		if( false !== strpos(parent::current(), 'Printer_') ){
			return true;
		}
		return false;		
	}
}

//Create a new Iterator for the array
//Create a RecursiveArrayIterator around our array
//Create a RecursiveIteratorIterator around that so we can easily navigate it
//Create a PrintFilter interator around that so we can filter only values starting with Printer_
$iterator = new PrinterFilter( new RecursiveIteratorIterator( new RecursiveArrayIterator( $printers ) ) );

//Simply iterate over the iterator add new keys as necessary
//Increment existing keys.
$counts = array();
foreach( $iterator as $key => $value ){
	if( isset( $counts[$value] ) ){
		++$counts[$value];
	} else {
		$counts[$value] = 1;
	}
}

print_r($counts);
Array
(
    [Printer_B] => 3
    [Printer_C] => 1
    [Printer_A] => 2
)
mschroeder 251 Bestower of Knowledge Team Colleague

What have you tried so far?

mschroeder 251 Bestower of Knowledge Team Colleague

Hopefully this illustrates something that might get you on your way.
I also applied some corrections to your code in general.
Tried to comment as much as possible.

//THERE IS A FORM ON ANOTHER PAGE WITH TEXTBOX NAMED "search",
//THAT COMES TO THIS PAGE.

//Global variables should be CAPITALIZED functions should not unless they are capitalized.
$search = $_POST['search'];

//Get words from search string		
$words = explode(' ',$search);

//Drop any empty search terms and trim remaining ones to avoid any extra whitespace
$words = array_map('trim', array_filter($words));

//Format the search terms into a string surrounded by single quotes
//e.g. 'word1 word2 word3'
$search_terms = sprintf("'%s'", implode(' ', $words) );

//Connect to the database
//Should REALLY be using mysqli not mysql functions
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ($sql_connect_error);
mysql_select_db($dbname);
						
//Do a Boolean full-text search on the searchkey column
//searchkey MUST have an index to work IN BOOLEAN MODE
//@see http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html
$sql = 'SELECT * FROM items WHERE MATCH(\'searchkey\') AGAINST ('.$search_terms.' IN BOOLEAN MODE)';
mschroeder 251 Bestower of Knowledge Team Colleague

Create hashes for the common fields that change. I'm thinking the title and content/body of each article. Store these two hashes with each item in your database.

When you process the feed again, generate the same hashes and look for any records where both hashes match. If you find a result disregard the item from the rss feed as it is identical to one in the database already.

When you find a mismatched title or body hash, update whichever of the fields does not match with the changes.

When you find no match on the title or body hash, insert the new item into your database.

mschroeder 251 Bestower of Knowledge Team Colleague

Try this:

<?php

$handle = fopen('ftp://user:password@ftp.server.com/path/to/image.jpg', 'rb');

header("Content-type: image/jpeg");
echo stream_get_contents($handle);

fclose($handle);

I just ran this code locally and could pull from a remote ftp server without any issue.
Essentially what would change is you would need to specify headers like you did originally and read the stream from the ftp connection to the browser. This should work for any file, just watch for timeouts.

mschroeder 251 Bestower of Knowledge Team Colleague

Do you need to use cURL for this? Why not use the FTP functions in php?
http://php.net/manual/en/book.ftp.php

You could also use the ftp://wrapper http://docs.php.net/manual/en/wrappers.ftp.php
with the filesystem functions

mschroeder 251 Bestower of Knowledge Team Colleague

I understand that there is some theoretical benefit in separating the view part from the logic and variables but I'm not sure if there is a real payback to make it worthwhile. Any thoughts on (real) benefits?

It is not a theoretical benefit to separate the view from logic, it is a real benefit. By separating the view from your logic you create another component that can be replaced on the fly.

For example, you have a site that sells a product. We'll say the url is domain.com/product/####, to view a specific product. When a user browses to that url, the system is looking for a format parameter (format/html, format/json, format/xml) it doesn't find one so the controller defaults to rendering the default html view. This might produce a page of a shopping cart for someone to buy the product directly from you. Now you have a third party who comes to you and says they would also like to sell your cogs in their store.

In a system where the view and logic is intermixed, you would need to replicate the page and/or code and adapt it to be some kind of readable format. If the logic and view is separated, its just a matter of rendering a different view. So the additional retailer says I can read any kind of json data in, so you create a json view that takes an array representation of your product model and json_encode it, and serve it …

mschroeder 251 Bestower of Knowledge Team Colleague
mysql> quit

You also have to finish statements from the command prompt with semi-colons.

show databases;

If you can access it via the command line and everything is working, from your localhost you should NOT have a firewall/port issue as the request never leaves the local machine.

mschroeder 251 Bestower of Knowledge Team Colleague

Can you access mysql via the command line? If so can you successfully log in as your root user?

mschroeder 251 Bestower of Knowledge Team Colleague

-ardav

Since xml is very well structured it would be relatively trivial to serialize an array or object returned from a database into xml automatically if needed. It also gives a very defined point to introduce caching into your system where the cache would be an xml fragment or entire document.

You're not really storing data in the xml long-term you're more so using it as an intermediate.

When I first played with the concept I was really worried about the performance overhead that the serializing to xml might introduce, but I was really surprised when I started benchmarking it in terms of speed and memory usage.

mschroeder 251 Bestower of Knowledge Team Colleague

But what about the simplicity of:

<?php foreach( $users as $user): ?>
<option value="<?php echo $value; ?>"><?php echo $value; ?></option>
<?php endforeach; ?>

There is shorthand syntax for almost, if not, all control structures in php.
If you were to use short php tags, which I will never, advocate you'd get <?=$value?> instead.

But it really is just semantics, if it works for your needs and it is a simple solution than it is a good solution.

As far as xml/xslt/xpath/xquery goes, it is a really powerful set of tools because they are not just relevant to php. In fact most browsers have very good support natively.

The following is simplified from a w3school example.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
	<cd>
		<title>Empire Burlesque</title>
		<artist>Bob Dylan</artist>
		<country>USA</country>
		<company>Columbia</company>
		<price>10.90</price>
		<year>1985</year>
	</cd>
</catalog>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <tr>
        <td><xsl:value-of select="catalog/cd/title" /></td>
        <td><xsl:value-of select="catalog/cd/artist" /></td>
      </tr>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

The general idea is that you supply an xml document to an xslt template and the template then pulls its data from the xml.

In PHP the transformation would work something like:

$doc = new DOMDocument();
$xsl = new XSLTProcessor();

$doc->load('/path/to/xsl/template.xsl');
$xsl->importStyleSheet($doc);

//Load XML from string		
$doc->loadXML('xml string...');
$html = $xsl->transformToXML($doc);
		
echo $html;
mschroeder 251 Bestower of Knowledge Team Colleague

Alright, I'll bite the bullet and throw some fuel on the fire.

Having more than a decade of php development under my belt now, I've run the gamut of template engines. I've even spun a few of my own over the years, but alas I've settled back into using purely php in my views.

Template engines are great in theory, they separate your logic from your display. Until you work with a designer who takes one look at your template language and pitches a fit, because they don't get it, and they don't want to get it.

In my opinion it is reinventing the wheel, adding a layer to your view rendering (in mvc terms) that takes a template and then has to parse over your code to replace some form of tags with values and also be able to find and execute logic, that just replaces it with php.

I've yet to find substantial reason to defend using {$variable} vs. <?php echo $variable;?> The earlier requires understanding of the template library and Rain is very simple compared to most. But when looking at some of the popular engines out there the template syntax becomes infinitely more complex than using natural php.

Now, if you want to talk REAL template languages, than I would highly advocate XSLT. I've used this in several cases and have really enjoyed working with it as a template engine/language. Using the PHP XSL extension (http://php.net/manual/en/book.xsl.php) you can simply …