I've been trying to change some code for a validation script so that it doesn't include goto, as I want to run my scripts on a webhost, and unfortunately most of them don't really have 5.3 or later.
The code is meant to use a value generated by rand for a unique validation number. If it finds it already in the DB, it will append 1 on to the number as many times as it needs to until it finds a usable number. Pretty straightforward. I know it's terrible practice for a MySQL query, but it's really just a simple script for practice.
The code is as follows:
function gen_val($val)
{
$query = mysql_query("SELECT val_id FROM users_tmp WHERE val_id=$val");
$row = mysql_fetch_array($query);
if ($row[0]==$val) {
gen_val($val+1);
} else {
return $val;
}
}
$val_x=gen_val(rand());
This returns a value '0' if the value already existed in the DB. Function works fine if there's no similar value already, so I think there's a problem with the function recursing. I don't think I really know how to use it properly, so please go ahead and educate me.
Cheers.
Asher
You forgot to return the result of your recursion.
return gen_val($val+1);
Correct me if I'm wrong, but you want to get a unique ID for each user. MySQL has this feature.
Related
I got confronted with this "problem" several times already, I fix it the same way but I feel dirty just by thinking how I solved it.
Let's say I work with Drupal 8 and that I need to modify several select form's default value, "-Any-" by "Select...".
This is how I proceed each time :
if(isset($form['field_children_charge_value'])) {
$form['field_children_charge_value']['#options']['All'] = t('Select...');
}
if(isset($form['field_evolution_target_id'])) {
$form['field_evolution_target_id']['#options']['All'] = t('Select...');
}
// And so on
I feel bad writing like this, but, for my defense, I didn't have a lot of of PHP theory while learning, I directly got the practical courses.
an elseif expression would only work once since the first condition will match the pre requisite, and it won't bother checking if some other condition would work too.
I also got the problem once with javascript, and I did the same thing.
So, is there a better syntax, and if yes, what is it?
Been years since I coded in php, but this seems like a general "issue".
You can save all the fields in an array, and then use a for-each loop to execute the operation on each of them:
$fields = ["field1", "field2", "..."];
foreach($fields as $field) {
if(isset($form[$field])) {
$form[$field]['#options']['All'] = t('Select...');
}
}
Are there any reasons to not to use die($result) to return Ajax request result in PHP? Please note that this is theoretical question, about code semantics.
Simple example (of course functions may be much complicated and return different values).
JS:
<script>
function checkLogin(login){
$.post('/ajax/check',{'login':login},function(res){
if(res == 1) return 1; else return 0;
}
}
</script>
PHP:
<?php
$db = mysql_connect(...);
$login = mysql_real_escape_string(stripslashes($_POST['login']));
$res = mysql_query("SELECT * FROM project.users WHERE login = '$login'");
if(mysql_num_rows($res)) die('0'); else die('1');
?>
PS. I know tha that mysql_*() functions are deprecated, no need to comment that. I simply like using them and will. As far as it will be possible.
EDIT:
I wonder why noone noticed that checkLogin() function has no sense, as request is async, and function always returns undefined ;-)
Since die() does not send any HTTP error status, there is no problem using it to return a string for an ajax call, but what stays there to say is, for the readability of the code, I don't think it's a good idea, but other than that, for functionality, there is no problem with it,since it outputs the message.
but also, now that's it's said, you have to take into consideration cases like CLI PHP in which the returned integer can really mean something for the shell(just for mentioning).
I would say that no, you don't want to do this. It is not made to return something to an ajax call, it is an equivalent to exit(), and you can give it a status.
That is just opinion though, but one that does have to do with semantics: it isn't meant to be used as a sort of echo, so don't use it as one.
The fact that you can have it 'return' an integer (as in, that works), but if you'd put in 255 it will not because it is reserved makes it tricky and unreadable.
So sure, while syntactically it works for values like '0', it would consider it bad form to use a language structure to return arbitrary messages, as it cannot return all messages.
Yes, there's a problem. In your too simple case no, but imagine this:
die($Result);
How will that behave? You don't know what that will do, since you don't know the type of $Code. As hank pointed out, if it's an integer it won't print anything. So you have a line of code that will behave differently depending of $Result. It seems very prone to heisenbugs.
PHP documentation:
Note: PHP >= 4.2.0 does NOT print the status if it is an integer.
A better solution would be to improve the control of the flow:
if ($this_is_NOT_an_ajax_call) {
// Do what you need to do
}
else {
echo $Result;
}
I've developed a habit of renaming my SELECT statement variable and I'm interested to know if it is necessary or not.
Here some typical code that I use:
$sql = ("SELECT * FROM tbl_one");
if(!$result_sql = $mysqli->query($sql))
{
// Error code here
}
while($a = $result_sql->fetch_assoc())
{
echo $a;
}
$sql2 = ("SELECT * FROM tbl_two");
if(!$result_sql2 = $mysqli->query($sql2))
{
// Error code here
}
while($b = $result_sql2->fetch_assoc())
{
echo $b;
}
For some reason I'm afraid there will be issues if I reuse the same $sql variable over again unless I rename it.
It's always good to have a different different variable for each statement you have as per coding standards even though PHP does not mind using same variable again and again.
It's just a string, so you shouldn't care. Its fine to use the same variable again if you don't need the previous value anymore.
Theoretically I opt not to reuse variable names for this sort of code, because of the risk of accidentally not overwriting one of them and getting strange results.
Then again, that problem doesn't go away just because you try to force yourself to remember to increment a number stuck on the end of the variable name.
Over time, as my code has improved, I've found that I very rarely need or want to execute multiple MySQL queries within a single PHP function, so the problem goes away entirely.
tl;dr: If I had a gun to my head, though... yes, I'd probably do it the same way you did. It's entirely subjective, though.
I have a pretty nasty error I can't get rid of. Here's the function causing the issue:
function get_info_by_WatIAM($WatIAM, $info) {
$users_info = array();
exec("uwdir -v userid={$WatIAM}", $users_info);
foreach ($users_info as $user_info) {
$exploded_info = explode(":", $user_info);
if (isset($exploded_info[1])){
$infoArray[$exploded_info[0]] = $exploded_info[1];
}
}
return $infoArray[$info]; }
Here's what's calling the function:
} elseif ( empty(get_info_by_WatIAM($_POST['ownerId'])) ) { ...
I would really appreciate any suggestion. Thanks very much!
If the code doesn't make sense, here's a further explanation: exec uses a program that stores information on all the users in a school. These include things like faculty, name, userid, etc. The $_POST['ownerId'] is a username -- the idea is that, upon entering a username, all of the user's information is automatically filled in
You do not need empty around function calls, in fact empty only works with variables and not functions (as you see). You only need empty if you want to test a variable that may not be set for thruthiness. It is pointless around a function call, since that function call must exist. Instead simply use:
} else if (!get_info_by_WatIAM($_POST['ownerId'])) { ...
It does the same thing. For an in-depth explanation, read The Definitive Guide To PHP's isset And empty.
empty can only be used on variables, not on expressions (such as the result of calling a function). There's a warning on the documentation page:
Note:
empty() only checks variables as anything else will result in a parse
error. In other words, the following will not work: empty(trim($name)).
Just one of PHP's best-left-alone quirks.
One workaround is to store the result in a variable and call empty on that, although it's clunky. In this specific case, you can also use
if (!get_info_by_WatIAM(...))
...although in general, if (empty($a)) and if(!$a) are not equivalent.
get the value of this
$a = get_info_by_WatIAM($_POST['ownerId'])
then chack
empty($a)
it will work
As you all probably know, do loops execute at least once, even if the statement is false — while the while loop would never execute even once if the statement is false.
When are do loops useful? Could someone give me a real life example?
They're basically useful when you want something to happen at least once, and maybe more.
The first example that comes to mind is generating a unique ID (non sequentially) in a database. The approach I sometimes take is:
lock table
do {
id = generate random id
} while(id exists)
insert into db with the generated id
unlock table
Basically it will keep generating ids until one doesn't exist (note: potentially an infinite loop, which I might guard against depending on the situation).
The Do loop is very powerfull if you have to check multiple files etc. Due to the guarentee of iteration it will work all the way through.
do {
if($integer > 0) { $nameoffile[0]++; }
else { $nameoffile[0] = $nameoffile[0].$integer; }
$integer++;
} while(file_exists("directory/".$nameoffile[0].".".$nameoffile[1]));
Next to what has already been answered, you can do crude stuff like this with a do:
do
{
if ($cond1) break;
if ($cond2) continue;
do_something();
} while(true/false);
Which is a modification of a switch loop, which allows continue. You can simulate goto similarities in case goto is not available and similar.
It must not make your code more readable, so it's often not suggested to do that. But it technically works.