php script optimisation - php

I'm not a php guru, need your help.
I have a php form with select menu. The menu is formed form the customers table e-mails. I've used the following code:
for($i = 0; $i < sizeof($customers_table); $i++){
echo '<option value="'.$customers_table[$i]['id'].'">'.$customers_table[$i]['email'].'</option>';
}
The base is rather big, so it takes time to form the option field. Is there any way to optimize the script so it will work faster.
Thank you.

As the size does not change, store it:
$size = sizeof($customers_table);
for ($i = 0; $i < $size; $i++) {
echo '<option value="'.$customers_table[$i]['id'].'">'.$customers_table[$i]['email'].'</option>';
}
Then you can shorten the loop condition and reduce the array access:
$i = $size = sizeof($customers_table);
while ($i) {
$table = $customers_table[$size-$i--];
echo '<option value="'.$table['id'].'">'.$table['email'].'</option>';
}
Next part is the echo statement which can just output instead of concatinating strings before outputting them:
$i = $size = sizeof($customers_table);
while ($i) {
$table = $customers_table[$size-$i--];
echo '<option value="', $table['id'], '">', $table['email'], '</option>';
}
If this makes a difference, you need to metric. The largest time taken might be the amount of HTML you send to the browser. But that would be out of the scope of this fragment.
To improve the overall readability of the code I suggest using foreach:
foreach ($customer_table as $row)
{
echo '<option value="', $table['id'], '">', $table['email'], '</option>';
}
This generally is pretty fast as well.

As Andy said, it's not a good idea to optimize this script that way.
If you want significant time changes, you have to rethink the problem.
You have a list of customers, and if there is a problem of time, I assume that there are a lot. So, a drop-down list would be useless for a user.
There are other solutions, more efficient :
Using a sort of caching > Your html code will always be the same, so you just need to do the loop once, when you add, delete or update a customer, and store the html code in a script or database. So, each time your page is reloaded, you just have to retrieve the html code.
Do not load all the customers > The user doesn't need to see all the customers, just the ones he's interested in, so with some Ajax you can load the options while the user is typing (see this for example: jQuery Autocomplete)
Those solutions are the best for optimization, and if you combine them (caching and autocomplete above 3 characters typed) it will be even better for user experience too.

Related

How to display foreach loop response during iteration using jQuery or Ajax

is it possible to display foreach loop response during iteration using jQuery or Ajax ?
for($i = 0; $i < 1000; $i ++) {
echo $i;
echo '<br>';
}
I want to call the function using ajax and display $i value in each iteration. Is it possible ?
Like typically, I dont want to wait for full page forloop process end and then echo result.
PS: I am student of Software Engineering in 2nd semester. I am in learning process so please bear me for any foolish request.
Thanks and Regards.

Dynamic PHP website using POST arguments and recursive function

I'm creating a website using PHP for the logic part of it.
It is a dynamic test. A set of questions are presented to the user and depending on his answers, a new set of questions will appear, thus, the questions will always be different if the answers are different.
In the form of the test, I have used POST to get the answers of the user and the action is empty because I want the page to reload but with different arguments (POST) every time. I also use a recursive function that takes the ID's of the next questions to be presented and the level (set of questions) just to not get lost. This recursive function also uses the arguments in POST to, again, obtain the user's answers so it can get the next questions at my DB.
function searchTree($arrNodes, $nivel){
$nxtQ = array(); $j=1;
$arr=getPreguntas($arrNodes,$nivel); //arr has "question" objects
$numPreg=count($arr);
for ($i=0; $i < count($arr); $i++) {
$arrayA[$i] = treeRule($arr[$i]->idPreg); //Array[i] is the set of related rules
}
echo '<form action="" method="post">';
for ($i=0; $i < $numPreg; $i++) {
echo $arr[$i]->pregunta .'</br>';
insertHTML($arr[$i]->idPreg, $numPreg, $j, $nivel); //Add HTML
$j++;
}
echo '</br><input type="submit" id="buttonSend'.$nivel.'" name="buttonSend'.$nivel.'" value="Enviar respuesta">';
echo '</form>';
$button= 'buttonSend'.$nivel;
if(isset($_POST[$button])){ //If the user answered
for ($i=0; $i < count($arrayA); $i++) { //arrayA has all related rules
if(!empty($arrayA[$i])){ //At least one related rule
$radio = 'valorRadio'.($i+1).'_'.$nivel;
$node = 'idNode'.($i+1).'_'.$nivel;
$answ[$i] = analize($_POST[$radio],$_POST[$node],$arrayA[$i],$i+1, $nivel); //$answ is the set of related rules which happened to be true
if($answ[$i]!=null){
echo 'True related rule: '.$answ[$i].' </br> ';
}else{
echo 'Answer all questions';
}
}else{ //End of analysis
echo 'No related rules </br>';
}
}
$relatedMR = getmetaRules($arrayA);
for ($i=0, $j=0; $i < count($relatedMR); $i++) {
$res = analizeMR($relatedMR[$i], $arrayA);
if($res=='1'){
$nxtQ[$j] = getNxtQ($relatedMR[$i]); //nxtQ is the set of next questions' IDs
$j++;
}
}
if($nxtQ!=NULL){
$_POST=array();
$arrNodes = array();
searchTree($nxtQ,($nivel+1));
}else{
echo 'End of test';
}
}else{
time_sleep_until($_POST);//Wait for an answer
}
}
I call this function at the beginning of my program like this:
searchTree(initialNodes(1),1);
initialNodes() function only enters the DB and gets the questions with level 1.
The first and second set of questions are presented (kind of) correctly (the first set of questions is always present and the second one appears under it, but that can be fixed at front-end.), however, the third one if not working anymore. The POST arguments are there but the new questions and radio buttons do not appear.
First set and POSTFirst and second set and POSTThird attempt and POST
I created an easier example of this by not using "sets of questions" but only one question each time. The first and second questions work as I previously mentioned but for the third one, the second one is replaced by the third and the third by the fourth and so on.
I don't know if my program is getting confused by the names of my HTML elements, if my recursive function is wrong or something else.

PHP Populate dropdown menu values from database

I am a beginner trying to ouptut the values of dropdown menu from a database. I already automatically generate the values from database but the problem i am having is I want the the value that is being selected to be displayed.
Ideally im trying to update a Subject which I want to data to be displayed in an HTML page where each item could be updated. What i need is to be able to select the 'position' of the subject that is beeing selected.
Here is my code:
<p>Position:
<select name="position">
<?php
$sel_subject = get_all_subjects();
$subject_count = mysql_num_rows($sel_subject);
//$subject_count+1 because we are adding a subject
for($count=1; $count <= $subject_count+1; $count++) {
echo "<option value=\"{$count}\"";
if($sel_subject['position'] == $count) {
echo " selected='selected'";
}
echo ">{$count}</option>";
}
?>
</select>
You seem to be relying on $count to be some internal ID that remains static; given that it's just a monotonically advancing integer, this seems like a risky proposition. However, if you're comfortable with that, all you need to do is change the value in the last echo statement to be the subject name instead of $count. I would instead encourage you to use something meaningful to the database - for example, some people create an auto_increment field called subject_id and key off of that; others like to use UUIDs.
I would also generally suggest using a foreach loop instead of a for loop, as it tends to simplify the code (you don't have to worry about maintaining the counter, or creating fence post errors, etc.) Here's a brief example - I'm guessing a bit at what the actual data is that is available to you, hopefully you can extrapolate it to what you actually have.
<p>Position:
<select name="position">
<?php
$sel_subject = get_all_subjects();
foreach($sel_subject as $subject_num => $subject) {
echo '<option value="', $subject_num, '"';
if ($subject['selected']) {
echo 'selected="selected"';
}
echo '>', $subject['subject_name'], '</option>';
}

php countering in javascript doesn't work

okay here is my code :
var co = 0;
var comp = '';
<?php $i = 0;?>
while (co < <?php echo $db->count_rows(); ?>)
{
if ((parseInt(value) >= <?php echo $mfr[$i] ?>) && (parseInt(value) <= <?php echo $mto[$i] ?>))
{
comp = 'T';
break;
}
co++;
<?php $i++; ?>
}
i'm still learning about this whole php and javascript thing, and i know there are many things that i still had to work to to improve my understanding to this both language. that's why i really need your help in this
i'm trying to get the while iteration to work so i can compare the variable from javascript with variable from php which took the value from database. the php variable ('$mfr' and '$mto'), as you can see, is an array. now i want it to look at every element of both and if it meets the condition then it will update the variable 'comp' and stop the whole while iteration
but the problem is the '$i' variable doesn't do the iteration thing. it runs only once so my '$mfr' and '$mto' value doesn't go anywhere. how can i fix this so i can compare the javascript value with the php '$mfr' and '$mto' value?
your help would be much appreciated, thank you :)
EDIT
well, it is actually a function of custom validation for jqgrid.
and i do know that php is a server-side and javascript is a client-side language theoretically, though i don't really know it is practically
what i'm actually trying to do is when a user input a value and submit it, the system will check whether the value that was entered are between value of 'fromid' and 'toid' column of a table in database
here is my full code of the function
function checkid(value)
{
var co = 0;
var comp = '';
<?php $i = 0;?>
while (co < <?php echo $db->count_rows(); ?>)
{
if ((parseInt(value) >= <?php echo $mfr[$i] ?>) && (parseInt(value) <= <?php echo $mto[$i] ?>))
{
comp = 'T';
break;
}
co++;
<?php echo $i++; ?>
}
if (comp != 'T')
{
return [true, "", ""];
}
else
{
return [false, "Value entered is already between a range. Please try again!", ""];
}
}
while this is how i got the '$mfr' and '$mto' variable
<?php
$db=new database($dbtype, $dbhost, $database, $dbuser, $dbpassword, $port, $dsn);
$db->query("select fromid, toid from CORE_ID");
$i = 0;
while($row = $db->get_row())
{
$mfr[$i] = $row[fromid];
$mto[$i] = $row[toid];
$i++;
}
?>
if theres any better way to do this, then please do tell me
Typically, PHP is for server side logic and JS is for client side logic. If you want to send a value from JS to be processed in PHP, you'll probably need to use something like AJAX, which jQuery makes pretty easy with jQuery.ajax().
Getting the client value to be processed is the difficult part. Once you can do that, rewriting your code logic in full PHP should not be difficult.
EDIT: If I'm misunderstanding where variable value comes from, please say so!
EDIT 2: It looks like you want to have client input compared to server side data. JS will not have access to your PHP variables unless they are specifically sent there. Likewise, you can send your JS value to the server for validation in the PHP.
In your case, you could use JSON to send send the JS your validation dates. Assuming you don't have too many dates, it will probably be faster than sending a value to the server and waiting for a response.
I found a good example of using JSON at another post. You can send an array like:
<?php
$xdata = array(
'foo' => 'bar',
'baz' => array('green','blue')
);
?>
<script type="text/javascript">
var xdata = <?php echo json_encode($xdata); ?>;
alert(xdata['foo']);
alert(xdata['baz'][0]);
// Dot notation can be used if key/name is simple:
alert(xdata.foo);
alert(xdata.baz[0]);
</script>
For your code, you could put $mfr and $mto into a single 2D array. Here is how your new JS might look, assuming xdata contains $mfr and $mto:
function checkid(value) {
var co = 0, comp = '', i = 0, nrows = xdata.mfr.length;
while (co < nrows) {
if ((parseInt(value) >= xdata.mfr[i]) && (parseInt(value) <= xdata.mto[i])) {
comp = 'T';
break;
}
co++;
i++;
}
if (comp != 'T') {
return [true, "", ""];
} else {
return [false, "Value entered is already between a range. Please try again!", ""];
}
}
You have a loop in your Javascript, not your PHP. So the PHP is only going to get executed once. You need to rethink your approach. Without knowing what the script is supposed to actually achieve it's difficult to provide working code, but you at least need to put the loop into the PHP instead of the Javascript.
Before I can answer you should understand what's going on exactly:
PHP is being executed on the server, then sends back the result (HTML and Javascript) to the client (the browser).
Javascript is being executed on the client side. So this only starts after PHP is completely done. For this reason you can't mix Javascript and PHP.
Check the source of the page, then you'll see exactly what the server returns (what HTML/Javascript PHP generates) and you'll get a better insight of what happens.
Now, if you understand this, you may be able to solve your own problem. I don't exactly know what you want to do, but I can advice you that if you need Javascript to check values from the database, you should generate Javascript using PHP that defines these values in the Javascript like for example this:
var my_js_var = <?=$my_php_var?>
var another_var = <?=$another_one?>
Now they are defined in Javascript and you can use them (and check them).
When you have a large database it can become inefficient to do it like this and you might want to look into a technology called AJAX, which allows Javascript to do a request to the server and get back data from a PHP script.
You would also want to do this if there's data involved you don't want to be publicly viewable (because everyone can look into the source of your page.

Using MySQL Databases and PHP to Populate forms

I am contemplating taking the next step with my PHP applications and making the option fields dynamic. That would open the doors for more automation.
I have drop downs throughout my project, they are used to select a specific user and I update them manually when a new user is added (which is also a manual process). But if i take the first step and make these drop downs become populated by a MySQL Database, then i can move on to dynamic user creation.
I know how I can achieve this, but I am curious about some other alternatives (If there is any).
Here is what I would do..
$query = ** MySQL Select * From Database Query **
echo '<select name="usernames">';
while($row == mysql_fetch_array($query))
{
echo '<option>' . $row['username'] . '</option>';
}
echo '</select>';
So my questions is, would you do this differently? And why? Thanks!
What you are doing will work fine. I like to make it into a function so that if I ever need that dropdown on another page I dont have to write a lot of code over again.
function userDD()
{
$query = ** MySQL Select * From Database Query **
$html = '<select name="usernames">';
while($row == mysql_fetch_array($query))
{
$html .= '<option>' . $row['username'] . '</option>';
}
$html .= '</select>';
return $html;
}
This code does exactly what your code does except it doenst use echo. Instead you use a variable ($html) to store all of the data then when you are done you return it.
Your way is fine, but two things need to be changed:
- Run htmlentities() or htmlspecialchars() on all echoed HTML to avoid XSS. Unless you already sanitized it at database entry time but I find this practice silly.
- Add a value attribute to each <option> tag, otherwise you won't be able to retrieve the username selected. I suggest using the username's corresponding ID or something else that's unique to that user. If it's a string, use htmlentities/htmlspecialchars on it too.
php file
$users = getUsers();
include('template.tpl');
template
<select name="username">
<?php foreach( $users as $user ): ?>
<li><?= e( $user['username'] ) ?></li>
<?php endforeach; ?>
</select>
e is a function that escapes strings to prevent xss attacks
I wouldn't put an SQL query in the same document as my output...
I'd create a document containing all SQL queries, in functions, and include that file. Just to keep things seperated.

Categories