PHP odd string-related performance issue - php

I have a class that is building some HTML using data stored in an array. There are around 100 items in this array. Each item includes information like company name, a description, and flags for the different programming languages the company supports. I am doing string concatenation as I build the HTML for each item.
I have noticed that performance suddenly takes a huge hit when I append the programming language data. I see the page rendering timer jump from 0.15 secs to ~0.60 secs. This time includes grabbing the same data from the database each time. I can consistently get the performance to jump between these 2 times but commenting/uncommenting the following line of code:
$html .= '<div class="programmingLanguages"><strong>Programming Languages</strong> '.implode(', ', $progLanguagesArray).'</div>';
I've also been able to get the same performance drop by appending a long test string, something like this:
$html .= 'testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest';
What's especially bizarre is that I have another line of code that uses the same 'implode' function and does NOT make any significant difference in performance:
$html .= '<div class="integrationMethods"><strong>Integration Methods:</strong> '.implode(', ', $intMethodsArray).'</div>';
Does anybody have any insight into what might be going on here? I am doing tons of concatenation like this elsewhere in my code and haven't seen anything like this before. At this point, I'm stumped.
Here's the full class:
class DeveloperView {
public static function getHtml($developers) {
$html = '';
$html .= '<div>';
$html .= '<div>';
$count = 0;
foreach ($developers as $developer) {
$url = $developer['attributes']['url'];
$phone = $developer['attributes']['phone'];
$company = $developer['attributes']['desc'];
$active = $developer['attributes']['active'];
$desc = $developer['object_value'];
$intMethodsArray = array();
if ($developer['attributes']['m1']) { $intMethodsArray[] = 'method 1'; }
if ($developer['attributes']['m2']) { $intMethodsArray[] = 'method 2'; }
if ($developer['attributes']['m3']) { $intMethodsArray[] = 'method 3'; }
if ($developer['attributes']['m4']) { $intMethodsArray[] = 'method 4'; }
if ($developer['attributes']['m5']) { $intMethodsArray[] = 'method 5'; }
$progLanguagesArray = array();
if ($developer['attributes']['dotnet']) { $progLanguagesArray[] = '.Net (C# or VB.Net)'; }
if ($developer['attributes']['asp']) { $progLanguagesArray[] = 'Classic ASP'; }
if ($developer['attributes']['cf']) { $progLanguagesArray[] = 'Cold Fusion'; }
if ($developer['attributes']['java']) { $progLanguagesArray[] = 'Java'; }
if ($developer['attributes']['php']) { $progLanguagesArray[] = 'PHP'; }
if ($developer['attributes']['perl']) { $progLanguagesArray[] = 'Perl'; }
if ($developer['attributes']['other']) { $progLanguagesArray[] = 'Other'; }
$html .= '<div class="';
if ($count % 2 == 0) {
$html .= 'listingalt';
} else {
$html .= 'listing';
}
$html .= '">';
$html .= '<div class="developerPhone">'.$phone.'</div>';
$html .= '<a class="ext_link" target="_blank" href="'.$url.'">'.$company.'</a>';
$html .= '<div>';
if (!empty($intMethodsArray)) {
$html .= '<div class="integrationMethods"><strong>Integration Methods:</strong> '.implode(', ', $intMethodsArray).'</div>';
}
if (!empty($progLanguagesArray)) {
$html .= '<div class="programmingLanguages"><strong>Programming Languages</strong> '.implode(', ', $progLanguagesArray).'</div>';
}
$html .= '</div>';
$html .= '<p>'.$desc.'</p>';
$html .= '</div>'."\n";
$count++;
}
$html .= '</div></div>';
return $html;
}
}

Now that I can provide an answer, I'll just post my follow-up comment as the 'answer'...
I did indeed have a 'bug' in my timer, in that it was calculating the end processing time AFTER the echo of the HTML. So the amount of data being sent to the browser was effecting the processing time, where I was expecting to see the time spent processing BEFORE transmitting any data.

Related

PHP foreach $output variation?

I need a little help on getting a rule in to output something else if a certain variable is called.
To break it down I have the following listed:
private $zebra_moto_symbol = array
( "ES400", "MC9500", "MC9200", "MC9190", "MC9094", "MC9090", "MC9097", "MC9060",;
and using this code it pulls the models into the page in a list:
public function manufacturer_models_list() {
$manu_name = $this->manufacturer_name;
$output = "<ul>";
sort($this->$manu_name);
foreach($this->$manu_name as $model) {
$output .= "<li>" . "" . $model . "</li>";
}
$output .= "</ul>";
$output .= "<p class=\"clear\"></p>";
$output .= "Arrange A Repair";
return $output;
}
On all but two of these, I need it display the repair.php link, however on two these need to be different. What would I need to input to make this happen?
Thanks in advance (sorry, this one stumped me).
:)
You can use a switch statement for this.
<?
public function manufacturer_models_list() {
$manu_name = $this->manufacturer_name;
$output = "<ul>";
sort($this->$manu_name);
foreach ($this->$manu_name as $model) {
switch($model) {
//Output NOT repair.php on this list of strings
case "ES400":
case "MC9500":
$output .= "<li>DIFFERENT OUTPUT</a></li>";
break;
//default is the action that happens if none of the previous conditions are met
default:
$output .= "<li>" . "" . $model . "</li>";
break;
}
}
$output .= "</ul>";
$output .= "<p class=\"clear\"></p>";
$output .= "Arrange A Repair";
return $output;
}
?>
Read more about Switch Statements
If I understood correctly, what you want is to have a different output on certain values.
I would think about have another array to hold the values that you want a different output and you can do something like this:
$different_output_array = ['ES400', 'MC9500']; # you can add new elements any time
and just modify your function to something like this:
public function manufacturer_models_list() {
$manu_name = $this->manufacturer_name;
$output = "<ul>";
sort($this->$manu_name);
foreach($this->$manu_name as $model) {
if(in_array($model,$different_output_array))
{
$output .= "<li>" . "" . $model . "</li>";
}
else
{
$output .= "<li>" . "" . $model . "</li>";
}
}
$output .= "</ul>";
$output .= "<p class=\"clear\"></p>";
$output .= "Arrange A Repair";
return $output;
}
Hope this can help.

Mixing PHP and HTML for Search Results Page

i'm working on setting up a page that uses PHP to layout the page, but i also need this PHP HTML code inserted into the PHP page for a search function. The search is done on a different page, and then the action is sent to the results page. I'm trying to get the PHP and HTML to mix together. I've tried using echo to no success. Basically i need the PHP HTML code to put the results into the $layout->content("");
<?php
require_once($_SERVER["DOCUMENT_ROOT"].'/layout/layout.inc.php');
require_once($_SERVER["DOCUMENT_ROOT"].'/functions/general.inc.php');
$layout = new default_layout();
$layout->title('IT KB Search');
$layout->content("<div class='border'>");
$layout->content('<h1>IT Support Knowledge Base - Search Results</h1>');
if (isset($_GET['q'])) {
$query = rawurlencode( strip_tags($_GET['q']));
$timestamp = time();
$baseUrl = 'https://oursite.atlassian.net/wiki';
$url = $baseUrl.'/rest/api/content/search?cql=space=KB%20AND%20type=page%20AND%20title~'.$query;
// To enable authenticated search:
// $url .= "&os_username=$username&os_password=$password";
$response = file_get_contents($url);
$response = json_decode($response);
$results = $response->results;
Echo '<div>';
Echo ' <ol>';
foreach($results as $item) {
Echo ' <li><strong><a href="';
$baseUrl. $item-> _links-> webui
Echo ' " target='_blank'>';
$item->title
Echo ' </a></strong></li>';
}
Echo ' </ol></div><hr>';
}
$layout->content("</div>");
$layout->render();
?>
You can to store the HTML to a string and then pass it to the $layout->content() function, like this...
<?php
require_once($_SERVER["DOCUMENT_ROOT"].'/layout/layout.inc.php');
require_once($_SERVER["DOCUMENT_ROOT"].'/functions/general.inc.php');
$layout = new default_layout();
$layout->title('IT KB Search');
$layout->content("<div class='border'>");
$layout->content('<h1>IT Support Knowledge Base - Search Results</h1>');
if (isset($_GET['q'])) {
$query = rawurlencode( strip_tags($_GET['q']));
$timestamp = time();
$baseUrl = 'https://oursite.atlassian.net/wiki';
$url = $baseUrl.'/rest/api/content/search?cql=space=KB%20AND%20type=page%20AND%20title~'.$query;
// To enable authenticated search:
// $url .= "&os_username=$username&os_password=$password";
$response = file_get_contents($url);
$response = json_decode($response);
$results = $response->results;
# Change Starts
$html = '<div>';
$html .= '<ol>';
foreach($results as $item) {
$html .= '<li><strong><a href="';
$html .= $baseUrl. $item-> _links-> webui;
$html .= '" target="_blank">';
$html .= $item->title;
$html .= '</a></strong></li>';
}
$html .= '</ol></div><hr>';
$html .= '</div>';
$layout->content($html);
# Change Ends
}
$layout->content('</div>');
$layout->render();

recursive function inside for loop

I m trying to create html in the controller instead of js.
There is an array with unknown depth of arrays.
$tree = $repo->childrenHierarchy();
and a function who reads the array and returns a string of html with values from array elements.
public function recursive($tree) {
$html = "";
foreach ($tree as $t) {
$html = $html . '<li> <span><i class="fa fa-lg fa-minus-circle"></i>' . $t['title'] . '</span>';
if ($t['__children'] != null) {
$html = $html . '<ul>';
$this->recursive($t['__children']);
$html = $html . '</ul>';
} else {
$html = $html . '</li>';
}
return $html;
}
My problem is that i cant hold the total string because everytime the function calls itself the var html is initialised, need to hold the string something like global but cant figure how.
After looking at this a little more, I don't think it really looks like a problem that the $html is initialized in the recursive calls. It seems to me that it actually should start as empty for the children. But it doesn't look like you're appending the children to the $html string you already have going. I think you need
$this->recursive($t['__children']);
to be instead
$html .= $this->recursive($t['__children']);
there shouldnt be anything wrong with just storing that value in class property while action ?
public $html = "";
public function recursive($tree) {
foreach ($tree as $t) {
$this->html = $this->html . '<li> <span><i class="fa fa-lg fa-minus-circle"></i>' . $t['title'] . '</span>';
if ($t['__children'] != null) {
$this->html = $this->html . '<ul>';
$this->recursive($t['__children']);
$this->html = $this->html . '</ul>';
} else {
$this->html = $this->html . '</li>';
}
return $this->html;
}

Wordpress Search Results in Order

One of my clients websites, www.kevinsplants.co.uk is not showing the search results in alphabetical order, how do I go about ordering the results in alphabetical order?
We are using the Shopp plugin and I believe its that plugin that is generating the results!
Cheers, Brad
case "orderby-list":
if (isset($Shopp->Category->controls)) return false;
if (isset($Shopp->Category->smart)) return false;
$menuoptions = Category::sortoptions();
$title = "";
$string = "";
$default = $Shopp->Settings->get('default_product_order');
if (empty($default)) $default = "title";
if (isset($options['default'])) $default = $options['default'];
if (isset($options['title'])) $title = $options['title'];
if (value_is_true($options['dropdown'])) {
if (isset($Shopp->Cart->data->Category['orderby']))
$default = $Shopp->Cart->data->Category['orderby'];
$string .= $title;
$string .= '<form action="'.esc_url($_SERVER['REQUEST_URI']).'" method="get" id="shopp-'.$Shopp->Category->slug.'-orderby-menu">';
if (!SHOPP_PERMALINKS) {
foreach ($_GET as $key => $value)
if ($key != 'shopp_orderby') $string .= '<input type="hidden" name="'.$key.'" value="'.$value.'" />';
}
$string .= '<select name="shopp_orderby" class="shopp-orderby-menu">';
$string .= menuoptions($menuoptions,$default,true);
$string .= '</select>';
$string .= '</form>';
$string .= '<script type="text/javascript">';
$string .= "jQuery('#shopp-".$Shopp->Category->slug."-orderby-menu select.shopp-orderby-menu').change(function () { this.form.submit(); });";
$string .= '</script>';
} else {
if (strpos($_SERVER['REQUEST_URI'],"?") !== false)
list($link,$query) = explode("\?",$_SERVER['REQUEST_URI']);
$query = $_GET;
unset($query['shopp_orderby']);
$query = http_build_query($query);
if (!empty($query)) $query .= '&';
foreach($menuoptions as $value => $option) {
$label = $option;
$href = esc_url($link.'?'.$query.'shopp_orderby='.$value);
$string .= '<li>'.$label.'</li>';
}
}
return $string;
break;
http://wordpress.org/extend/plugins/sort-searchresult-by-title/
This is a plug-in that seems to do what you want.
You need to edit the template file of the search page and add to the search query parameters orderby title, as opposed to the default ordering which is by time of publication
It is not a good idea to edit the core code. And lucky for you it is not necessary. You can edit/create your own template file collection-search.php and style it any way you want.
There is more info on template files here.

My nested anchor tags won't nest?

I'm trying to build my site's navigation using recursion and I can't seem to get the <div> tags to nest properly. I'm not even sure if this code is the path I should go down, but It's a start. The desired output:
<div class="parent">1</div>
<div class="child">
1.1
1.2
1.3
</div>
<div class="parent">2</div>
<div class="child">
2.1
2.2
2.3
</div>
Here is my database:
Here's the code I'm trying to get working: (THIS CODE NEEDS A LOT OF WORK)
/* here's the call */
$this->buildNav($array,NULL,false);
private function buildNav($array,$parent,$loop)
{
$html = '';
$class = ($loop) ? 'child' : 'parent';
$tag = '<div>%s</div>';
$child = false;
foreach($array as $item)
{
if($item['parent']===$parent)
{
$child = true;
$html .= '<div>'.$item['category_name'];
$html .= $this->buildNav($array,$item['category_id'],true);
$html .= '</div>';
$html .= ''.$item['category_name'].'';
}
if(!$child)
{
$tag = '';
}
}
return sprintf($tag,$html);
}
UPDATE
Per shapeshifter's advice I went away from recursion and just called a function to get the children ... beautiful idea ;) Here's the code:
private function buildNav($array,$parent)
{
$html = '';
foreach($array as $item)
{
if($item['parent'] === NULL)
{
$html .= '<div class="parent">'.$item['category_name'].'</div>';
$html .= '<div class="child">'.$this->getChildren($array,$item['category_id']).'</div>';
}
}
return $html;
}
private function getChildren($array,$parent)
{
$html = '';
foreach($array as $item)
{
if($item['parent']===$parent)
{
$html .= ''.$item['category_name'].'';
}
}
return $html;
}
Thanks again to the others who provided such profound alternatives and or direction ;)

Categories