I've read all the other articles on in_array, and still don't understand why mine is givng odd results. I'm inheriting this code from someone else, and don't fully understand why they did certain things. When a user logs in, data is grabbed from a db, one of the fields being their "level". 1 is an admin, 2 a regular user, etc. Once the data is grabbed from the db, we put the user level (stored as a:1:{i:0;s:1:"2") into an array:
$user_level = unserialize($this->result['user_level']);
$_SESSION['unt']['user_level'] = $user_level;
Later we check to see if this is an admin:
error_log(print_r($_SESSION['abc']['user_level'])); //this is always "1"
if (in_array('1', $_SESSION['abc']['user_level'])) { //should be yes, correct?
Yet somehow the if statement never evaluates as true, even though the SESSION variable is 1. What am I missing?
$_SESSION['abc']['user_level'] doesn't appear to be an array. Looks like you want one of the following.
If gettype($_SESSION['abc']['user_level']) is 'integer':
if ($_SESSION['abc']['user_level']) === 1) {
If gettype($_SESSION['abc']['user_level']) is 'string':
if ($_SESSION['abc']['user_level']) === '1') {
If gettype($_SESSION['abc']['user_level']) is 'string' and its value actually contains the quotes:
if ($_SESSION['abc']['user_level']) === '"1"') {
If it was an array the output would have this structure, not just "1":
Array
(
[0] => 1
)
Even though I noticed closing bracket } missing from your input string I just assumed that you probably might have missed while copy-pasting .
a:1:{i:0;s:1:"2"
So in_array is not the problem but your input string is the problem .With display_errors setting Off you would not see any error when you try to unserialize it .
You could use the below function to check if the input is a valid string to unserialize :
// Copied from http://www.php.net/manual/en/function.unserialize.php
function is_serialized( $str )
{
return( $str == serialize( false ) || #unserialize( $str ) !== false );
}
Then something along these lines :
$inputString = 'a:1:{i:0;s:1:"2";}'; // Is valid and is holding one array of info
// $inputString = 'a:1:{i:0;s:1:"2"'; // Invalid as is missing a closing baracket }
if( ! is_serialized( $inputString ) )
{
echo 'Is not serialized';
}
else
{
$user_level = unserialize( $inputString );
$_SESSION['unt']['user_level'] = $user_level; // Is an array
// Note the second argument as was already pointed by #AsksAnyway
error_log( print_r( $_SESSION['unt']['user_level'] , true ) );
var_dump( in_array( '1' ,$_SESSION['unt']['user_level']) );
var_dump( in_array( '2' ,$_SESSION['unt']['user_level']) );
}
Related
I could retrieve my session variable which represents access locations as follows,
$_SESSION['access']
This session variable contains some strings as follows,
dummy1,dummy2,dummy3,dummy4
As an example $_SESSION['access'] can be dummy1 or dummy1,dummy2 or dummy1,dummy2,dummy3 or dummy2,dummy3,dummy4 likewise. Are there any method to find contains type of function?
Ex:
if($_SESSION['access']`.contains("dummy1")){
//do somthing,
}
Or do I need to use mysql function to retrieve what I need?
Not a method but function - as string is not an object in PHP.
The function is called str_contains.
Use it like this on your example:
if (str_contains($_SESSION['access'], "dummy1")) {
//do somthing,
}
The function is part of the language only recently (needs PHP 8).
For older PHP versions strstr was often used for this purpose (it also returns a substring of the original string, but only in case it is contained - which is exactly what we need here).
One would do so like this:
if (strstr($_SESSION['access'], "dummy1")) {
//do somthing,
}
This may be a bit more verbose, but works:
if ( array_key_exists( "access", $_SESSION ) ) {
$arrVals = explode( ',', $_SESSION["access"]) ;
$key = "dummy1" ; // doesn't have to be hard-coded here, just for demo
$b = array_search( $key, $arrVals ) ;
if ( $b !== false ) {
/// do your thing
echo ( "found $key<br/>") ;
}
}
I have a VERY simple code, I dont know what I am doing wrong. I am sending post variables with Ajax, there are 3 checkboxes (an array) name="options[]".. I am receiving the right array, if I check Option1, Option2 or Option3, I get the correct Array.. but when I try to check and confirm them with isset() or with array_key_exist() it does not give me the right answers.. For example, if I only check Option 1 and 3, I get the following in the POST
[options] => Array
(
[0] => option_one
[1] => option_two
)
I need to do some action only IF the certain key does NOT exist in the array.. I tried something like below..
if (array_key_exists("option_one", $_POST['options'])) {
echo "Option one exists";
} else {
echo "option one does not exist";
}
it returns flase results, then I tried using ! (not) before it, that returns the same result. Then I tried with isset($_POST['options']['option_one']) without any luck.. then I tried the following function to check again within the array..
function is_set( $varname, $parent=null ) {
if ( !is_array( $parent ) && !is_object($parent) ) {
$parent = $GLOBALS;
}
return array_key_exists( $varname, $parent );
}
and used it like this
if (is_set("option_one", $_POST['options'])) {
echo "Option one exists";
} else {
echo "option one does not exist";
}
nothing works, it simply returns false value. I tried with $_REQUEST instead if $_POST but no luck, I have read many threads that isset() or array_key_exists() returns false values.. What is the solution for this ? any help would be highly appreciated.. I am tired of it now..
regards
option_one is not a key in the array, it's a value. The key is 0. If anything, use:
in_array('option_one', $_POST['options'])
array_key_exists looks for the keys of the arrays. You are looking for the value. :)
What you want is
/**
* Check wheter parameter exists in $_POST['options'] and is not empty
*
* #param $needle
* #return boolean
*/
function in_options($needle)
{
if (empty($_POST['options']))
return false;
return in_array($needle, $_POST['options']);
}
Are you sure you are getting the correct information in your options[] array? If you clicked option 1 and option 3, shouldn't the array look something like this?
[options] => Array
(
[0] => option_one
[1] => option_three
)
Since isset() is a language construct and not a function, you may be able to rework the validation to be more efficient.
function in_options($needle)
{
//Checking that it is set and not NULL is enough here.
if (! isset($_POST['options'][0]))
return false;
return in_array($needle, $_POST['options']);
}
The function empty() works, but I think that $_POST['options'][0] only needs to be checked for isset() at this point.
I want to keep this short. I don't know if I have the terminology correct, but I got this example from the Codeigniter handbook Vol.1.
if (count($args) > 1 || is_array($args[0]))
I've run into this problem numerous times. Depending on the datatype different tests are more appropriate. Some tests will just fail in unexpected ways.
How does one determine the most appropriate, and possibly, the most concise test?
Just to be clear I'm looking for the most effective way to test if an object/variable is ready to use, regardless of the datatype, if that's possible.
Also I don't want the solution to apply merely to lists like in the example. It should be widely applicable.
Just use empty
if(!empty($args)){
echo 'Array is set, not empty and not null';
}
use empty() bool empty ( mixed $var )
http://www.php.net/manual/en/function.empty.php
Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSE. empty() does not generate a warning if the variable does not exist.
I've been using the following function for a while.
You can add your own test for all possible variable types.
function is_valid_var($var)
{
if ( isset( $var ) ) {
// string
if ( is_string( $var ) && strlen( $var ) == 0 ) return false;
// array
elseif ( is_array( $var ) && count( $var ) == 0 ) return false;
// unknown
else return true;
}
return false;
}
How can you make the if -clause which do this and this if
there is no variable in the URL by PHP?
there is no variable which has value in the URL by PHP?
Examples of the URLs which should be true for the if -clause for #1:
www.example.com/index.php
example.com/index.php
example.com/index.php?
Examples of the URLs which should be true for the if -clause for #2:
example.com/index.php?successful_registration
example.com/index.php?successful_login
The following is my unsuccessful if -clause for $1
if (isset($_REQUEST[''])) {
// do this
}
if ( 0 == count( $_GET ) )
{
// do this
}
or
if ( empty( array_keys( $_GET ) ) )
{
// do this
}
or
if ( '' == $_SERVER['QUERY_STRING'] )
{
// do this
}
You'd want to check $_GET and $_SERVER["query_string"].
If the query string is empty, you've got just the base url. If the query string is not empty, but one of the $_GET variables is empty, you've got an invalid domain.
If statements are not loops. You might call it an condition though.
if(isset($_REQUEST['successful_registration'])) {
//do this
}elseif(isset($_REQUEST['successful_login'])) {
//do this
}else{
//do this
}
If have a problem on my site that users can post empty messages if they use space.
Code:
if (isset($_POST['submit'])) {
// check for empty fields
if (empty($_POST['headline']) || empty($_POST['text']) ||
empty($_POST['forum_id'])) {
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
// No errors? Save.
else {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
}
How can I fix this?
trim() the text inputs. You can do that easily like this:
// get input vars and trim space
$callback = array('filter' => FILTER_CALLBACK, 'options' => 'trim');
$fields = filter_input_array(INPUT_POST, array(
'headline' => $callback,
'text' => $callback,
'forum_id' => $callback,
));
// check for empty fields by counting how many are set
if ( count($fields) != count(array_filter($fields)) ) {
// something was unset
}
The empty function checks for variables that meet a set criteria, from the manual
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
Your $_POST fields actually contain something like this
" ";
This isn't and empty string, but a string that's filled with whitespace characters.
Before using empty(), trim() the white-space from your POSTed values
$trimmed_post = array();
foreach($_POST as $key=>$value){
$trimmed_post[$key] = $value;
}
if(!empty($trimmed_post['headline'])){
//...
}
You don't need to put the new values into a new array, but I'm not a big fan of changing what's in the auto-generated superglobals.
One final note, you can't do something like this
if(!empty(trim($_POST['headline']))){
//...
}
because the empty function expects to be passed an actual variable. You could do something like this instead
if('' != trim($_POST['headline'])){
//...
}
This is probably the best approach to take. You reduce the number of functions that you need to call, users can post entries with a value of 0, and the code is more explicit about what it does. Another form you'll see is
if(trim($_POST['headline'])){
}
This works because PHP evaluates an empty string ('') as false, and a non empty string as true. I tend to avoid this form because I've found a lot of PHP bugs crop up around misunderstandings on how the equality operators get boolean values out of certain types. Being explicit helps reduce occurrences of these types of bugs.
Just a quick note: You're injecting the value of $_POST['forum_id'] into the SQL; that's not a good idea, since a user could manipulate that value as desired, even if it is coming from a hidden field. It would be wise to escape the value, or at least pass it through intval() and ensure it's an integer (assuming integral post identifiers).
I agree that trimming is the way to go. Here's a much easier way to go about it:
$_POST = array_map('trim', $_POST);
Try
if (!empty($_POST['headline']) && !empty($_POST['text']) &&
!empty($_POST['forum_id']))
For the logic.
You'd have to switch it around though.
UPDATE to clarify:
if (isset($_POST['submit']) && !empty($_POST['headline']) &&
!empty($_POST['text']) && !empty($_POST['forum_id'])) {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
else
{
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
}
I trim every $_GET & $_POST variable as soon as the app starts. try something like this:
function trimArray(&$array) {
if (empty($array)) {
return;
}
foreach ($array as $k => $v) {
if (! is_array($v)) {
$array[$k] = trim($v);
} else {
trimArray($v);
}
}
}
if (! empty($_GET)) {
trimArray($_GET);
}
if (! empty($_POST)) {
trimArray($_POST);
}
Right after checking for a submission:
foreach ( $_POST as $key => &$value ) $value = trim($value);
edit in response to asker's comment:
Odd that it didn't work as above. Here was my exercise to confirm it would.
tbramble#wayfarer:~$ php -a
Interactive shell
php > $arr = array('one',' two', ' three ');
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
php > foreach ( $arr as $key => &$value ) $value = trim($value);
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
Must have something to do with working on a superglobal instead of a normal array.