Debug simple php while code - php

I am getting this error: "Fatal error: Can't use function return value in write context in D:\Programas\wamp\www\away\index.php on line 18". Line 18 being the if statement.
Can anyone help me out on this? Thanks.
$vars = array("first_date_month", "first_date_day", "last_date_month", "last_date_day", "resume_date_month", "resume_date_day", "pay_date_month", "pay_date_day", "pay_time_hour", "pay_time_minutes");
$err_flag = false;
$i = 0;
while ($i < count($vars) and $err_flag == false)
{
if ( (!isset($_GET($vars[$i])) or ($_GET[$vars[$i] == "0") )
$err_flag = true;
$i++;
}

Maybe I'm not seeing well, but:
if ( (!isset($_GET($vars[$i])) or ($_GET[$vars[$i] == "0") )
You got a really awful mixup of parenthesis and square brackets. There's no such thing as
$_GET()
Big typo you have to correct.

Your code is a mess.
$_GET is an associative array and not a function (you are using the function call syntax passing $vars[$i] as an argument). In the second $_GET there's one ] missing.
Line 18 should be:
if ( (!isset($_GET[$vars[$i]]) or ($_GET[$vars[$i]] == "0") )

My take at it:
$vars = array("first_date_month", "first_date_day", "last_date_month", "last_date_day", "resume_date_month", "resume_date_day", "pay_date_month", "pay_date_day", "pay_time_hour", "pay_time_minutes");
foreach ($vars as $var) {
if ($err_flag = empty($_GET[$var]))
break;
}
8)
I assume the marked answer has... well.. answered the problems in your code, so just throwing out some optimizations:
using foreach() instead of while/for
is simple in many cases where we are
just iterating over an array - we can get the value and also the key if needed.
using the empty() function (returns true for anything null, false, 0, "", "0")
exit the loop when you're done using break

$_GET is a variable, an array -- and not a function.
It means you have to use array-access, with [], to get the data it contains.
So :
$_GET[$vars[$i]]
instead of
$_GET($vars[$i])
for the first time you are using $_GET.
And, for the second time, you forgot to close one ] ; which means you need to use :
$_GET[$vars[$i]]
instead of
$_GET[$vars[$i]
In the end, you while-loop should look like this :
while ($i < count($vars) and $err_flag == false)
{
if ( !isset($_GET[$vars[$i]]) or $_GET[$vars[$i]] == "0" ) {
$err_flag = true;
}
$i++;
}
Note I also added {} arround the body of the if condition ; this way, if you ever have to add something, you won't risk forgetting those ;-)

Change your line 18 if... to:
if ( (!isset($vars[$i])) or ($vars[$i] == "0") )
$err_flag = true;
$i++;
This mainly because I -and this is purely personal, I suspect- don't like using the $_GET[...] throughout the script; assign:
$variable_from_GET[] = $_GET['variable_name'];
and then use the $variable_from_GET array variable in your conditions which you -I presume- you did since you had a $vars array.

Related

Cleaning up a very long if statement

I have a very long list of strings called $stringfilter1 $stringfilter2 etc all the way up to $stringfilter50
I have another string $reporteremail and I want to make a conditional statement whereby if any of the $stringfilter strings is present in the $reporteremail, some code is executed. At the moment my code looks like this and it works:
if (stripos($reporteremail, $stringfilter1) !== false || stripos($reporteremail, $stringfilter2) !== false || stripos($reporteremail, $stringfilter3) !== false [...]) {
runcode();
}
This is very very long though. I have cut it short here.
I was wondering if there's a cleaner, more efficient way to do this?
EDIT:
I am writing a plugin for a bug tracker. The strings are entered on another page in text boxes. I access them on this page by running a function that looks like
$t_filter = plugin_config_get( 'filter1' );
$stringfilter1 = string_attribute( $t_filter1 );
I would agree looping through an array would be the best way to do this. How can I push each new string onto the end of an array without having to write that snippet above out 50 times?
How can I push each new string onto the end of an array without having to write that snippet above out 50 times?
Try this:
$needles = [];
for ($i = 0; $i < 50; $i++) {
$t_filter = plugin_config_get("filter$i");
$needles[] = string_attribute($t_filter);
}
I have a very long list of strings called $stringfilter1 $stringfilter2 etc all the way up to $stringfilter50
[...]
This is very very long though. I have cut it short here.
I was wondering if there's a cleaner, more efficient way to do this?
Try this, it should go after the code block above.
$flag = false;
foreach ($needles as $needle) {
if (stripos($reporteremail, $needle) !== false) {
$flag = true;
break;
}
}
if ($flag) {
runcode();
}
The code above works by iterating through the $needles array and sets a flag if stripos doesn't return false. After it's finished iterating, it checks if the flag is true, if so, this means that one of the needles was found in the array.
EDIT
Alternatively, you could do it all in one loop, which is both faster and more efficient.
$flag = false;
for ($i = 0; $i < 50; $i++) {
$t_filter = plugin_config_get("filter$i");
$needle = string_attribute($t_filter);
if (stripos($reporteremail, $needle) !== false) {
// One of the needles was found in $reporteremail.
runcode();
break;
}
}
You don't need a loop. First put all your filters in an array instead of having them in separate variables. I would try to do this by modifying the input source rather than doing it in your PHP script. (Based on your comments I'm not sure if that's possible or not, so maybe you do need a loop like the one in the other answer.) Then you can use str_ireplace to check for your filter strings in the $reporteremail. (This will not modify $reporteremail.)
str_ireplace($filters, '', $reporteremail, $count);
if ($count) {
// run code
}
The $count parameter will contain a count of how many replacements were performed. If it's nonzero, then at least one of the filters was found in $reporteremail.

Fatal error: Can't use function return value in write context in C:\xampp\htdocs\IM\IMlogin.php on line 36 [duplicate]

I'm getting this error and I can't make head or tail of it.
The exact error message is:
Fatal error: Can't use function return
value in write context in
/home/curricle/public_html/descarga/index.php
on line 48
Line 48 is:
if (isset($_POST('sms_code') == TRUE ) {
What could be going on here?
Here's the full function:
function validate_sms_code() {
$state = NOTHING_SUBMITED;
if (isset($_POST('sms_code') == TRUE ) {
$sms_code = clean_up($_POST('sms_code'));
$return_code = get_sepomo_code($sms_code);
switch($return_code) {
case 1:
//no error
$state = CORRECT_CODE;
break;
case 2:
// code already used
$state = CODE_ALREADY_USED;
break;
case 3:
// wrong code
$state = WRONG_CODE;
break;
case 4:
// generic error
$state = UNKNOWN_SEPOMO_CODE;
break;
default:
// unknown error
$state = UNKNOWN_SEPOMO_CODE;
throw new Exception('Unknown sepomo code: ' . $return_code);
break;
}
} else {
$state = NOTHING_SUBMITED;
}
dispatch_on_state($state);
}
This also happens when using empty on a function return:
!empty(trim($someText)) and doSomething()
because empty is not a function but a language construct (not sure), and it only takes variables:
Right:
empty($someVar)
Wrong:
empty(someFunc())
Since PHP 5.5, it supports more than variables. But if you need it before 5.5, use trim($name) == false. From empty documentation.
You mean
if (isset($_POST['sms_code']) == TRUE ) {
though incidentally you really mean
if (isset($_POST['sms_code'])) {
if (isset($_POST('sms_code') == TRUE ) {
change this line to
if (isset($_POST['sms_code']) == TRUE ) {
You are using parentheseis () for $_POST but you wanted square brackets []
:)
OR
if (isset($_POST['sms_code']) && $_POST['sms_code']) {
//this lets in this block only if $_POST['sms_code'] has some value
for WORDPRESS:
instead of:
if (empty(get_option('smth')))
should be:
if (!get_option('smth'))
Correct syntax (you had a missing parentheses in the end):
if (isset($_POST['sms_code']) == TRUE ) {
^
p.s. you dont need == TRUE part, because BOOLEAN (true/false) is returned already.
This can happen in more than one scenario, below is a list of well known scenarios :
// calling empty on a function
empty(myFunction($myVariable)); // the return value of myFunction should be saved into a variable
// then you can use empty on your variable
// using parenthesis to access an element of an array, parenthesis are used to call a function
if (isset($_POST('sms_code') == TRUE ) { ...
// that should be if(isset($_POST['sms_code']) == TRUE)
This also could be triggered when we try to increment the result of a function like below:
$myCounter = '356';
$myCounter = intVal($myCounter)++; // we try to increment the result of the intVal...
// like the first case, the ++ needs to be called on a variable, a variable should hold the the return of the function then we can call ++ operator on it.
The problem is in the () you have to go []
if (isset($_POST('sms_code') == TRUE)
by
if (isset($_POST['sms_code'] == TRUE)
I also had a similar problem like yours. The problem is that you are using an old php version. I have upgraded to PHP 5.6 and the problem no longer exist.
Another scenario where this error is trigered due syntax error:
ucwords($variable) = $string;
i also ran into this problem due to syntax error. Using "(" instead of "[" in array index:
foreach($arr_parameters as $arr_key=>$arr_value) {
$arr_named_parameters(":$arr_key") = $arr_value;
}
This error is quite right and highlights a contextual syntax issue. Can be reproduced by performing any kind "non-assignable" syntax. For instance:
function Syntax($hello) { .... then attempt to call the function as though a property and assign a value.... $this->Syntax('Hello') = 'World';
The above error will be thrown because syntactially the statement is wrong. The right assignment of 'World' cannot be written in the context you have used (i.e. syntactically incorrect for this context). 'Cannot use function return value' or it could read 'Cannot assign the right-hand value to the function because its read-only'
The specific error in the OPs code is as highlighted, using brackets instead of square brackets.
Can be cause by wrong operator, =, when it should be ==
if(mysql_num_rows($result) = 1)
return $result;
else
return false;
This code throws this error
Note that = is assignment operator and not comparison operator. Fix is to change = to ==.

While loop: only Variables can be passed by reference error

I am running into a "Only variables should be passed by reference" error, because on the code I am using there is a line that does not put the explode() result into a variable. As required when using strict PHP standards.
However because the explode() function is used in a While loop I can't think of a appropriate solution.
My code looks like
function user_exists($username) {
rewind($this->fp);
while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))) {
if($lusername == $username)
return 1;
}
return 0;
}
Any suggestions on how to solve this?
I think maybe you need to sit back and break your code apart a bit and take a look at what is happening.
First, condition is while !feof($this->fp)
From the manual:
feof — Tests for end-of-file on a file pointer
One thing you will notice here is that feof() is only a test which returns true or false. It does not advance the pointer position while looping over, so while using this function, somewhere else in your while loop there needs to be something that advances the pointer or else you will have an infinite loop.
Second condition is:
trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))
First function from left to right is trim(), which returns a string. From our handy dandy comparison table we see that when doing if ((String) $var) it evaluates to false if and only if the string is empty ("") or the number zero as a string ("0"), otherwise it returns true. Personally I tend to really hate using if ((String) $var) (first because it's slightly unclear to newbies unless you know your comparison table well and second because 99% of the time people are doing that they are actually checking for string length, in which case I would want it to return true for the string "0"). So assuming that you don't need it to return false for "0" we could change this to strlen($var) > 0 and then manipulate the variable within the loop. That should greatly simplify things here.
So now we have:
while (!feof($this->fp) && strlen($var) > 0) { /*...*/ }
This will loop over until either we are at the end of the file or $var is an empty line. Everything else can be offloaded into the body of the while loop, so it is much easier to break apart.
So this is what we have now:
$line = rtrim(fgets($this->fp));
$lusername = array_shift(explode(":",$line)));
Uh-oh! There's that "nasty" error:
Strict Standards: Only variables should be passed by reference in /path/to/file.php on line x.
So we can see from here, the part producing the error is not explode(), but array_shift(). See also: Strict Standards: Only variables should be passed by reference
What this means is that since array_shift() modifies the array, it requires it to be by reference. Since you are not passing an actual variable but instead the result of a function, PHP is unable to modify it. It's similar to doing something like function($var) = 3;. Of course you can't do that. Instead you need to save the value to a temporary variable. So now we have:
$line = rtrim(fgets($this->fp));
$split = explode(":",$line);
$lusername = array_shift($split);
Woo hoo! No more warning message.
So putting this together, we now have:
while (!feof($this->fp) && strlen($lusername) > 0) {
$line = rtrim(fgets($this->fp));
$split = explode(":",$line);
$lusername = array_shift($split);
if($lusername == $username) {
return 1;
}
}
Also, as mentioned earlier, the fgets() will advance the pointer, which allows the !feof($this->fp) part in the while statement to vary.

Trying to remove an item from an array but it wont work

I dont really understand why this is not working, I am being returned to the correct header but the item is still in the array!
Here is the remove from array code:
<?php
session_start();
if ( !isset($_SESSION['username']) )
{
header("Location:loginform.php");
exit();
}
foreach ($_SESSION['list'] as $key => $disk)
{
if (($_SESSION['list'][$key]['bookisbn']) - ($_GET['bookisbn'])== 0)
{
unset($_SESSION['list'][$key]);
break;
}
}
header("Location: ".$_GET['location']);
exit();
?>
Thank you for any help you can offer
This is only a guess but the problem may lie in the fact that
$_GET['bookisbn']
is being treated as a string. Therefore if you cast it to an int
the if statement will return true removing the item from the
array.
Introduce this code:
// Casting the ISBN to an integer here
$bookISBN = (int) $_GET['bookisbn'];
if( ($_SESSION['list'][$key]['bookisbn'] - $bookISBN) == 0 ) {
// Unset item
}
I would listen to Artragis, but also try this:
You have parenthesis around each of the variables, but it's really the subtraction that has to equal zero. So, instead of:
if (($_SESSION['list'][$key]['bookisbn']) - ($_GET['bookisbn'])== 0)
{
unset($_SESSION['list'][$key]);
break;
}
Try:
if (($_SESSION['list'][$key]['bookisbn'] - $_GET['bookisbn']) == 0)
{
unset($_SESSION['list'][$key]);
break;
}
EDIT:
I would also cast both the Session and the GET variables as INTs, like one of the other posters mentioned, as well.
Try session_write_close() before the header. Perhaps is not saving.
You can also do this:
$mydata = $_SESSION['list'] ;
//do something with $mydata
$_SESSION['list'] = $mydata;
It will result in easier to read code, if you have other type of error, with this way you will not make the same mistake again.
You need to debug and test if line with unset is reachable.
You need to debug means you need to verify every program's step and every variable.
You need to test if line with unset is reachable means you have to echo something at the point of unset:
foreach ($_SESSION['list'] as $key => $disk)
{
var_dump("---\n",$_SESSION['list'][$key]['bookisbn'],$_GET['bookisbn']);
var_dump($_SESSION['list'][$key]['bookisbn'] - $_GET['bookisbn']);
var_dump($_SESSION['list'][$key]['bookisbn'] - $_GET['bookisbn'] == 0);
if ($_SESSION['list'][$key]['bookisbn'] - $_GET['bookisbn'] == 0)
{
unset($_SESSION['list'][$key]);
var_dump($_SESSION['list']);
break;
}
}
//comment out header to prevent moving out of page
#header("Location: ".$_GET['location']);
exit();
run this code and see if any of the values are wrong or unexpected.

PHP what is the best way to handle a variable that may not be set?

I have a foreach loop, that will loop through an array, but the array may not exist depending on the logic of this particular application.
My question relates to I guess best practices, for example, is it ok to do this:
if (isset($array))
{
foreach($array as $something)
{
//do something
}
}
It seems messy to me, but in this instance if I dont do it, it errors on the foreach. should I pass an empty array?? I haven't posted specific code because its a general question about handling variables that may or may not be set.
Just to note: here is the 'safest' way.
if (isset($array) && is_array($array)) {
foreach ($array as $item) {
// ...
}
}
Try:
if(!empty($array))
{
foreach($array as $row)
{
// do something
}
}
That's not messy at all. In fact, it's best practice. If I had to point out anything messy it would be the use of Allman brace style, but that's personal preference. (I'm a 1TBS kind of guy) ;)
I'll usually do this in all of my class methods:
public function do_stuff ($param = NULL) {
if (!empty($param)) {
// do stuff
}
}
A word on empty(). There are cases where isset is preferable, but empty works if the variable is not set, OR if it contains an "empty" value like an empty string or the number 0.
If you pass an empty array to foreach then it is fine but if you pass a array variable that is not initialized then it will produce error.
It will work when array is empty or even not initialized.
if( !empty($array) && is_array($array) ) {
foreach(...)
}
I would say it is good practice to have a 'boolean' other value that is set as 0 (PHP's false) to start, and any time some function adds to this array, add +1 to the boolean, so you'll have a definite way to know if you should mess with the array or not?
That's the approach I would take in an object oriented language, in PHP it could be messier, but still I find it best to have a deliberate variable keeping track, rather than try to analyze the array itself. Ideally if this variable is always an array, set the first value as 0, and use it as the flag:
<?PHP
//somewhere in initialization
$myArray[0] = 0;
...
//somewhere inside an if statement that fills up the array
$myArray[0]++;
$myArray[1] = someValue;
//somewhere later in the game:
if($myArray[0] > 0){ //check if this array should be processed or not
foreach($myArray as $row){ //start up the for loop
if(! $skippedFirstRow){ //$skippedFirstRow will be false the first try
$skippedFirstRow++; //now $skippedFirstRow will be true
continue; //this will skip to the next iteration of the loop
}
//process remaining rows - nothing will happen here for that first placeholder row
}
}
?>

Categories