How to refactor a long function? - php

I have a function that prepares a receipt output. But since it has all kinds of conditions it ends up being very long and difficult to understand..
How would one go about refactoring this? Any ideas?
If I split this into 100 small functions would that really be better?
public static function prepare_receipt($printer)
{
if (self::hasItems($printer['id']))
{
$output = '';
if ($_POST['pre_receipt'])
{
$output .= "======== Pre receipt =======\n\n\n";
}
/**
* Time and table
*/
if ($_POST['isTakeaway'] || $_POST["isDeliveryGuys"] || $_POST["isBolt"]) {
$output .= "Table: " . $_POST['table'] . "\n";
$output .= "Floor: " . $_POST['floor'] . "\n";
$output .= "Time: " . $_POST['takeawayTime'] . "\n";
if ($_POST['order_comment']) {
$output .= "Comment: " . removeSpecialChars($_POST['order_comment']) . "\n";
}
} else {
$output .= "Table: " . $_POST['table'] . "\n\n";
$output .= "Floor: " . $_POST['floor'] . "\n\n";
if ($_POST['order_comment']) {
$output .= "Comment: " . removeSpecialChars($_POST['order_comment']) . "\n";
}
}
$output .= "------------------------\n";
/**
* Food items
*/
foreach ($_POST['orderedItems'] as $orderedItem)
{
$has_unprinted_quantity = false;
if (isset($orderedItem['last_printed_quantity'])) {
$unprinted_quantity_count = intval($orderedItem['is_printed_quantity']) - intval($orderedItem['last_printed_quantity']);
if ($unprinted_quantity_count > 0) {
$has_unprinted_quantity = true;
}
}
if ( ($orderedItem['should_print'] &&
!$orderedItem['is_printed'] &&
$orderedItem['is_visible']) ||
$_POST['pre_receipt'] ||
$has_unprinted_quantity)
{
if (is_array($orderedItem['printers'])) {
$in_printer = in_array($printer['id'], $orderedItem['printers']);
} else {
$in_printer = in_array($printer['id'], json_decode($orderedItem['printers'], true));
}
if ( $in_printer || $_POST['pre_receipt'] )
{
if ($orderedItem['is_sidedish'] && !$_POST['pre_receipt']) {
continue;
}
if ($has_unprinted_quantity) {
$output .= $unprinted_quantity_count . 'x ';
} else {
$output .= $orderedItem['quantity'] . 'x ';
}
// We ned to split it for multiple lines...
$itemDescriptionParts = self::split($orderedItem['description']);
foreach ($itemDescriptionParts as $itemDescription) {
$itemDescriptionClean = removeSpecialChars($itemDescription);
$output .= $itemDescriptionClean;
}
// Add price for pre receipt
if ($_POST['pre_receipt']) {
$output .= " - " . number_format($orderedItem['price_with_discount'], 2, '.', ',');
}
if (!$_POST['pre_receipt']) {
if ($orderedItem['comments'] != '') {
$output .= " > " . removeSpecialChars(substr($orderedItem['comments'], 0, 27)) . "\n";
}
}
/** Side dishes */
if (isset($orderedItem['side_dishes']) && !$_POST['pre_receipt'])
{
foreach ($orderedItem['side_dishes'] as $side_dish) {
$output .= "\n + " . removeSpecialChars(substr($side_dish['description'], 0, 27)) . "\n";
}
}
$output .= "\n";
}
}
}
/**
* Sums
*/
/**
* Footer
*/
$output .= "------------------------\n";
if ($_POST['pre_receipt'])
{
$output .= "\nSubtotal: " . number_format($_POST['order']['subtotal'], 2, '.', ',') . "\n";
$output .= "Discount: " . number_format($_POST['order']['discount'], 2, '.', ',') . "\n";
$output .= "Total: " . number_format($_POST['order']['total'], 2, '.', ',') . "\n\n";
}
$output .= "Time: " . getTime() . "\n";
return $output;
}
else
{
return 'EMPTY';
}
}
Any pointers in the right direction would be much appreciated.

Refactoring works often well, if it follows semantics. In your case: You made already comments for different sections. This is often a sign for a function on it's own.
Just to give you an idea: How it may look like afterwards:
$output .= create_headline(...);
$output .= create_time_table(...);
$output .= create_separator();
foreach ($_POST['orderedItems'] as $orderedItem) {
$output .= create_food_item($orderedItem, $_POST['pre_receipt'], ...);
}
$output .= create_separator();
$output .= create_footer(...);
This will save time when searching for a bug in a certain area of the receipt.

I would advice https://en.wikipedia.org/wiki/Divide-and-conquer_algorithm, and your function already has comment that indicates how this function can be divided in multiple that has a single responsability.
I would also advice not to use $_POST directly, all input data must always be validated and possibly filtered. Data from input should be passed as dependency, to adhere dependency injection, see https://phptherightway.com/ for other good practices.
I would also avoid the use of string concatenation, store all the parts within an array and then join/implode them using a separator.

Looking at your code smart use of ternary operators and shifting the orderitem loop into different function can drastically reduce your code length by half. There is no need to create function for each operation like printing head, printing tail etc as the logic in those print is pretty simple and your code can prettry muddy and difficult to navigate if there are large number of unwanted functions. You can do something like below. Also note using . (dot) operator for string concatenation make your string less readable hence prefer printing variables with {} operator.
<?php
public static function prepare_receipt($printer)
{
if (self::hasItems($printer['id']))
{
$output = isset($_POST['pre_receipt']) ? "======== Pre receipt =======\n\n\n" : "" ;
//addiing time table
$output .= "Table: {$_POST['table']}. \n Floor: {$_POST['floor']}. \n";
//adding time if it is takeaway or isDeliveryGuys or isBolt
$output .= ($_POST['isTakeaway'] || $_POST["isDeliveryGuys"] || $_POST["isBolt"]) ? "Time: {$_POST['takeawayTime']}. \n" : "" ;
//adding order comment
$output .= $_POST['order_comment']) ? "Comment: {removeSpecialChars($_POST['order_comment'])} \n" : "" ;
//print order items
this->getOrderItems($_POST[orderedItems], &$output);
// footer
$output .= "------------------------\n";
if ($_POST['pre_receipt'])
$output .= "\nSubtotal: {number_format($_POST['order']['subtotal'], 2, '.', ',')} \n Discount: { number_format($_POST['order']['discount'], 2, '.', ',') } \n Total: {number_format($_POST['order']['total'], 2, '.', ',')} \n\n";
$output .= "Time: " . getTime() . "\n";
return $output;
}
else
{
return 'EMPTY';
}
}
?>
.

Related

How can i fit this comma problem with CSV file?

I have this code that creates a CVS file with the CF7 information the customer has provided, and it is attached into the mail I receive, the code is into functions.php.
The problem I have is that if a customer puts a comma into any field, like if he put on the name field John, Smith, it breaks the CSV
Do you have any idea how can I fix it?
//Create the shortcode which will set the value for the DTX field
function cf7dtx_counter(){
$val = get_option( CF7_COUNTER, 0) + 1; //Increment the current count
return $val;
}
add_shortcode('CF7_counter', 'cf7dtx_counter');
//Action performed when the mail is actually sent by CF7
function cf7dtx_increment_mail_counter(){
$val = get_option( CF7_COUNTER, 0) + 1; //Increment the current count
update_option(CF7_COUNTER, $val); //Update the settings with the new count
}
add_action('wpcf7_mail_sent', 'cf7dtx_increment_mail_counter');
// Add this to functions.php //
// Create CSV by scraping email using before_send_mail action //
add_action( 'wpcf7_before_send_mail', 'cf7_csv_creation' );
function cf7_csv_creation($cf7) {
// Allow to target the ID of specific form //
$form_id = $cf7->id();
// Check certain form by ID - remove this IF statement if not specific //
// Make sure the file is saved into wp-content to retieve it within WPCF7 settings as an attachement //
$user_register_csv = 'wp-content/uploads/csvs/csvreserva.csv';
// Create file contents - if you have more fields add them to the output below //
$output = "poblacio,tipus,data-entrada,data-sortida,PrimerCognom,SegonCognom,nom,Sexe,data-naixament,identificacio,Adreca,CodiPostal,Ciutat,Provincia,Pais,Telefon,Mobil,email,Estudis,Curs,Centre,Familiar,NIF-familiar,professio-familiar,Adreca-familiar,CodiPostal-familiar,Poblacio-familiar,Provincia-familiar,Pais-familiar,Mail-familiar,Telefon-familiar,Mobil-familiar,questionari-coneixament,questionari-aficions,accepto,num-registre,maildesti,titol,url,arxiu-dni,arxiu-universitat,arxiu-pagament,arxiu-dni-url,arxiu-universitat-url,arxiu-pagament,url,Submitted From,data,accepta-politica,ip,navegador";
$output .= "\n";
$output .= $_POST["residencia"] . ", ";
$output .= $_POST["menu-147"] . ", ";
$output .= $_POST["date-5"] . ", ";
$output .= $_POST["date-6"] . ", ";
$output .= $_POST["text-145"] . ", ";
$output .= $_POST["text-4445"] . ", ";
$output .= $_POST["text-144"] . ", ";
$output .= $_POST["radio-603"] . ", ";
$output .= $_POST["date-34"] . ", ";
$output .= $_POST["text-146"] . ", ";
$output .= $_POST["text-147"] . ", ";
$output .= $_POST["text-1478"] . ", ";
$output .= $_POST["text-149"] . ", ";
$output .= $_POST["text-150"] . ", ";
$output .= $_POST["menu-950"] . ", ";
$output .= $_POST["text-151"] . ", ";
$output .= $_POST["text-1521"] . ", ";
$output .= $_POST["email-775"] . ", ";
$output .= $_POST["text-200"] . ", ";
$output .= $_POST["text-201"] . ", ";
$output .= $_POST["text-202"] . ", ";
$output .= $_POST["text-301"] . ", ";
$output .= $_POST["text-302"] . ", ";
$output .= $_POST["text-313"] . ", ";
$output .= $_POST["text-303"] . ", ";
$output .= $_POST["text-304"] . ", ";
$output .= $_POST["text-305"] . ", ";
$output .= $_POST["menu-951"] . ", ";
$output .= $_POST["text-306"] . ", ";
$output .= $_POST["text-309"] . ", ";
$output .= $_POST["text-308"] . ", ";
$output .= $_POST["text-3048"] . ", ";
$output .= $_POST["text-543"] . ", ";
$output .= $_POST["text-697"] . ", ";
$output .= $_POST["Si"] . ", ";
$output .= $_POST["cf7-coutner"] . ", ";
$output .= $_POST["reserves#sample.com"] . ", ";
$output .= $_POST["Formulario recibido"] . ", ";
$output .= $_POST["https://www.sample.com"] . ", ";
$output .= $_POST["file-628"] . ", ";
$output .= $_POST["file-629"] . ", ";
$output .= $_POST["file-630"] . ", ";
$output .= $_POST[""] . ", ";
$output .= $_POST[""] . ", ";
$output .= $_POST[""] . ", ";
$output .= $_POST["1"] . ", ";
$output .= $_POST["_date"] . ", ";
$output .= $_POST["Si"] . ", ";
$output .= $_POST["_remote_ip"] . ", ";
$output .= $_POST["_user_agent"] . ", ";
$output .= $_POST["your-email"];
// Save contents to file //
file_put_contents($user_register_csv, $output);
}
// Clear file/user data after submission //
add_action('wpcf7_mail_sent', function ($cf7) {
$user_register_csv = 'wp-content/uploads/csvs/csvreserva.csv';
file_put_contents($user_register_csv, '');
// File cleared and ready to be rewritten on next submission //
});
// Remember - add the above path to the WPCF7 File attachment setting within the relevant form //
I think the guy that commented on you post has a better solution but alternatively you can add this line before you assign a value to $output
$_POST = str_replace(",","",$_POST);
This will replace all the commas in $_POST with an empty character so even if the user enters a comma it will get replaced with an empty character.
If you want to keep the commas that the user enters, you can enclose the $_POST variable in quotation marks when extending the value of the $output variable. For example:
$output .= '"'.$_POST["residencia"].'", ';

Associate attributes with products in opencart to generate xml file

The past couple of hours I am trying to generate an xml file like this
<?xml version="1.0" encoding="UTF-8"?>
<mywebstore>
<created_at>2010-04-08 12:32</created_at>
<products>
<product>
<id>322233</id>
<name><![CDATA[MadBiker 600 Black Polarized]]></name>
<link><![CDATA[http://www.mywebstore.gr/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.gr/product/322233.jpg]]></image>
<category id="23"><![CDATA[Sports > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
<manufacturer><![CDATA[SuperGlasses]]></manufacturer>
<description><![CDATA[This is the description.....]]></description>
<weight>350</weight>
<mpn>ZHD332</mpn>
<instock>N</instock>
<availability>Pre-order</availability>
</product>
<product>
...
</product>
</products>
</mywebstore>
from opencart.
I have written this piece of code
<?php
class ControllerFeedSkroutzXml extends Controller {
public function index() {
$this->language->load('feed/skroutz_xml');
if ($this->config->get('skroutz_xml_status')) {
$output = '<?xml version="1.0" encoding="UTF-8"?>';
$output .= '<mywebstore>';
$output .= '<created_at>' . date('Y-m-d H:i') . '</created_at>';
$output .= '<products>';
$this->load->model('catalog/product');
$products = $this->model_catalog_product->getProducts();
foreach ($products as $product) {
$attribute_groups = $this->model_catalog_product->getProductAttributes($product['product_id']);
//print_r($attribute_groups);
if (!empty($attribute_groups)) {
foreach ($attribute_groups as $attribute_group) {
if (!empty($attribute_group)) {
foreach ($attribute_group['attribute'] as $attribute) {
$attribute = array_filter($attribute);
if (!empty($attribute)) {
// [attribute_id] => 13, Color
if ($attribute['attribute_id'] == 13 && $attribute['text'] != '') {
$attribute_color = $attribute['text'];
}
// [attribute_id] => 16, Lens Technology
if ($attribute['attribute_id'] == 16 && $attribute['text'] != '') {
$attribute_lens_technology = $attribute['text'];
}
}
}
}
}
}
if ($product['special']) {
$final_price = number_format((float)$product['special'], 2, '.', '');
} else {
$final_price = number_format((float)$product['price'], 2, '.', '');
}
if ($product['quantity'] > 0) {
$instock = $this->language->get('instock_Y');
} else {
$instock = $this->language->get('instock_N');
}
$output .= '<product>';
$output .= '<id>' . $product['product_id'] . '</id>';
$output .= '<name><![CDATA[' . $this->language->get('category_name') . ' ' . $product['name'] . ' ' . $attribute_color . ' ' . $attribute_lens_technology . ']]></name>';
$output .= '<link><![CDATA[' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . ']]></link>';
$output .= '<image><![CDATA['. HTTP_IMAGE . $product['image'] . ']]></image>';
$output .= '<category id="' . $product['manufacturer_id'] . '"><![CDATA[ ' . $this->language->get('category_name') . ' > ' . $product['manufacturer'] . ' ]]></category>';
$output .= '<price_with_vat>' . $final_price . '</price_with_vat>';
$output .= '<manufacturer><![CDATA[' . $product['manufacturer'] . ']]></manufacturer>';
$output .= '<description><![CDATA[' . $product['meta_description'] . ']]></description>';
$output .= '<instock>' . $instock . '</instock>';
$output .= '<availability>' . $product['stock_status'] . '</availability>';
$output .= '</product>';
}
$output .= '</products>';
$output .= '</mywebstore>';
$this->response->addHeader('Content-Type: application/xml');
$this->response->setOutput($output);
}
}
}
?>
But the block of code that generates the attributes it doesn't work as expected.
A lot of my products don't have attributes (at least not yet), so what I want to accomplish is to show attributes right next to the name of the product
Example
Name: MadBiker 600
Attribute - Color: Black
Attribute - Lens Technology : Polarized
All together <name>MadBiker 600 Black Polarized</name>
Only if a product has attributes!
The above php code generates the <name>MadBiker 600 Black Polarized</name> to all empty of attributes products until it finds the next product with an attribute!
Could someone please point out where is the problem?
Thank you!
You aren't resetting the $attribute_lens_technology and $attribute_color with each iteration of the foreach. You need to reset these after the foreach loop definition
New foreach loop:
foreach ($products as $product) {
$attribute_lens_technology = false;
$attribute_color = false;
$attribute_groups = $this->model_catalog_product->getProductAttributes($product['product_id']);
//print_r($attribute_groups);
if (!empty($attribute_groups)) {
foreach ($attribute_groups as $attribute_group) {
if (!empty($attribute_group)) {
foreach ($attribute_group['attribute'] as $attribute) {
$attribute = array_filter($attribute);
if (!empty($attribute)) {
// [attribute_id] => 13, Color
if ($attribute['attribute_id'] == 13 && $attribute['text'] != '') {
$attribute_color = $attribute['text'];
}
// [attribute_id] => 16, Lens Technology
if ($attribute['attribute_id'] == 16 && $attribute['text'] != '') {
$attribute_lens_technology = $attribute['text'];
}
}
}
}
}
}
if ($attribute_lens_technology === false || $attribute_color === false) {
// Code here such as continue; if you want to skip products without both attributes
}
if ($product['special']) {
$final_price = number_format((float)$product['special'], 2, '.', '');
} else {
$final_price = number_format((float)$product['price'], 2, '.', '');
}
if ($product['quantity'] > 0) {
$instock = $this->language->get('instock_Y');
} else {
$instock = $this->language->get('instock_N');
}
$output .= '<product>';
$output .= '<id>' . $product['product_id'] . '</id>';
$output .= '<name><![CDATA[' . $this->language->get('category_name') . ' ' . $product['name'] . ' ' . $attribute_color . ' ' . $attribute_lens_technology . ']]></name>';
$output .= '<link><![CDATA[' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . ']]></link>';
$output .= '<image><![CDATA['. HTTP_IMAGE . $product['image'] . ']]></image>';
$output .= '<category id="' . $product['manufacturer_id'] . '"><![CDATA[ ' . $this->language->get('category_name') . ' > ' . $product['manufacturer'] . ' ]]></category>';
$output .= '<price_with_vat>' . $final_price . '</price_with_vat>';
$output .= '<manufacturer><![CDATA[' . $product['manufacturer'] . ']]></manufacturer>';
$output .= '<description><![CDATA[' . $product['meta_description'] . ']]></description>';
$output .= '<instock>' . $instock . '</instock>';
$output .= '<availability>' . $product['stock_status'] . '</availability>';
$output .= '</product>';
}
It's easier to write an xml file using simplexml than it is to manually try and output your own.
Nevertheless, here's a simple shorthand if statement to fix to your problem though (if attribute color is empty, it will append an empty string instead:
$output .= !empty($attribute_color) ? '<name><![CDATA[' . $this->language->get('category_name') . ' ' . $product['name'] . ' ' . $attribute_color . ' ' . $attribute_lens_technology . ']]></name>' : '';

Prepared PHP statement not printing out

I have a statement that is grabbing information from the database, and then is printed out after it is fully prepared.. For some reason though, my script is not printing out the information. I have it in this if statement:
if($community == ''){ print $community . "\n\n" . "END" . "\n"; } else { print $community; echo "hi";}
This prints out when it is ran:
() wrote:
But that is all it prints out. That is coming from the 8th $community .= line. So, my question is, why is it ONLY printing out () Wrote: and not all the variables as well?
// and ticker_symbol ='".$sym."'
$c_sql = "SELECT message_id, subject, author, FROM_UNIXTIME(datestamp,'%m-%d-%Y') AS formatted_datestamp, forum_id, body, thread, user_id FROM phorum_messages WHERE user_id=13423720 ORDER BY datestamp DESC LIMIT 5";
$c_result = mysql_query($c_sql,$connection) or die("Couldn't execute get query");
// Declare Variables
$body = $c_result['body'];
$forum_id = $c_result['forum_id'];
$user_id = $c_result['user_id'];
$author = $c_result['author'];
$formatted_datestamp = $c_result['formatted_datestamp'];
// Prepare the statement
if ($c_result != "") {
$community .= $forumPost = '<<<ENDL '. "\n";
$community .= $body . "\n";
$community .= 'ENDL;' . "\n";
$community .= '$forumPost = stripBBCode(strip_tags($forumPost));' . "\n";
$community .= "\n";
$community .= '<div class="comment">' . "\n";
$community .= '<table cellspacing="0" cellpadding="0" border="0" class="reply"><tbody><tr>' . "\n";
$community .= '<td width="90%"><b>'.$author.' ('.$formatted_datestamp.') wrote:</b><br />' . "\n";
$community .= '<p>'.iconv("ISO-8859-1//TRANSLIT", "UTF-8", $forumPost).'</p></td>' . "\n";
$community .= '</tr></tbody></table>'. "\n";
$community .= '</div>' . "\n";
}
// Print out the prepared statement
if($community = ''){ print $community . "\n\n" . "END" . "\n"; } else { print $community;}
When you are calling if($community = ''){ you only have one equals sign which will set $community to a blank string.
I think what you mean to do is if($community == ''){
It should have the double-equal:
if($community == '')
With a single = sign you're simply assigning an empty string to variable $community - and then checking whether it's true. Empty strings evaluate to false, hence you're getting into your else part - and losing your value in the process.
You only have one = sign
you need:
if($community == '') { etc...

How to generate .php files from .dll files for code completion?

Basically I have just successfully installed MongoDB and it's PHP extension. I want to use code completion in my IDE for the MongoDB php library and closest I have gotten to getting an answer is some stuff about PDT with Eclipse. I am not getting anywhere.
Ok after a lot of searching I found some code that helps me do just that! I will include the code here for others to use in case something happens to the git repo. All you have to do is write in the classes and functions you want to stub for code completion into these arrays $functions = array();
$classes = array(); https://gist.github.com/ralphschindler/4757829
<?php
define('T', ' ');
define('N', PHP_EOL);
$functions = array();
$classes = array();
$constant_prefix = 'X_';
$php = '<?php' . N;
$php .= '/**' . N . ' * Generated stub file for code completion purposes' . N . ' */';
$php .= N . N;
foreach (get_defined_constants() as $cname => $cvalue) {
if (strpos($cname, $constant_prefix) === 0) {
$php .= 'define(\'' . $cname . '\', ' . $cvalue . ');' . N;
}
}
$php .= N;
foreach ($functions as $function) {
$refl = new ReflectionFunction($function);
$php .= 'function ' . $refl->getName() . '(';
foreach ($refl->getParameters() as $i => $parameter) {
if ($i >= 1) {
$php .= ', ';
}
if ($typehint = $parameter->getClass()) {
$php .= $typehint->getName() . ' ';
}
$php .= '$' . $parameter->getName();
if ($parameter->isDefaultValueAvailable()) {
$php .= ' = ' . $parameter->getDefaultValue();
}
}
$php .= ') {}' . N;
}
$php .= N;
foreach ($classes as $class) {
$refl = new ReflectionClass($class);
$php .= 'class ' . $refl->getName();
if ($parent = $refl->getParentClass()) {
$php .= ' extends ' . $parent->getName();
}
$php .= N . '{' . N;
foreach ($refl->getProperties() as $property) {
$php .= T . '$' . $property->getName() . ';' . N;
}
foreach ($refl->getMethods() as $method) {
if ($method->isPublic()) {
if ($method->getDocComment()) {
$php .= T . $method->getDocComment() . N;
}
$php .= T . 'public function ';
if ($method->returnsReference()) {
$php .= '&';
}
$php .= $method->getName() . '(';
foreach ($method->getParameters() as $i => $parameter) {
if ($i >= 1) {
$php .= ', ';
}
if ($parameter->isArray()) {
$php .= 'array ';
}
if ($typehint = $parameter->getClass()) {
$php .= $typehint->getName() . ' ';
}
$php .= '$' . $parameter->getName();
if ($parameter->isDefaultValueAvailable()) {
$php .= ' = ' . $parameter->getDefaultValue();
}
}
$php .= ') {}' . N;
}
}
$php .= '}';
}
echo $php . N;

php howto unset static var

i have a function like this. i want reset the $output var first call.
function create_tree($tree_array, $reset = TRUE, $ul_class = FALSE) {
if($reset) unset($output); // NOT WORK!!!
static $output = '';
$class = '';
if ($ul_class) {
$class = ' class="' . $ul_class . '"';
}
$output .= '<ul' . $class . '>' . PHP_EOL;
foreach ($tree_array as $v) {
$output .= '<li>' . $v['name'] . '' . PHP_EOL;;
if (isset($v['children'])) {
create_tree($v['children'], false);
}
$output .= '</li>' . PHP_EOL;
}
$output .= '</ul>' . PHP_EOL;
return $output;
}
$output doesn't magically exist at that point in the function; it magically retains its value when the declaration is seen again.
if ($reset)
$output = '';

Categories