©
Ce document utilise Manuel du site Web PHP chinois Libérer
(PHP 4, PHP 5, PHP 7)
isset — 检测变量是否设置
$var
[, mixed $...
] )
检测变量是否设置,并且不是 NULL
。
如果已经使用 unset()
释放了一个变量之后,它将不再是
isset() 。若使用 isset()
测试一个被设置成 NULL
的变量,将返回 FALSE
。同时要注意的是一个 NULL
字节("\0")并不等同于
PHP 的 NULL
常数。
If multiple parameters are supplied then isset() will
return TRUE
only if all of the parameters are set. Evaluation goes from
left to right and stops as soon as an unset variable is encountered.
var
要检查的变量。
...
其他变量。
如果 var
存在并且值不是 NULL
则返回 TRUE
,否则返回 FALSE
。
版本 | 说明 |
---|---|
5.4.0 |
检查字符的非数字偏移量将会返回 |
Example #1 isset() 例子
<?php
$var = '' ;
// 结果为 TRUE,所以后边的文本将被打印出来。
if (isset( $var )) {
echo "This var is set so I will print." ;
}
// 在后边的例子中,我们将使用 var_dump 输出 isset() 的返回值。
// the return value of isset().
$a = "test" ;
$b = "anothertest" ;
var_dump (isset( $a )); // TRUE
var_dump (isset( $a , $b )); // TRUE
unset ( $a );
var_dump (isset( $a )); // FALSE
var_dump (isset( $a , $b )); // FALSE
$foo = NULL ;
var_dump (isset( $foo )); // FALSE
?>
这对于数组中的元素也同样有效:
<?php
$a = array ( 'test' => 1 , 'hello' => NULL , 'pie' => array( 'a' => 'apple' ));
var_dump (isset( $a [ 'test' ])); // TRUE
var_dump (isset( $a [ 'foo' ])); // FALSE
var_dump (isset( $a [ 'hello' ])); // FALSE
// 键 'hello' 的值等于 NULL,所以被认为是未置值的。
// 如果想检测 NULL 键值,可以试试下边的方法。
var_dump ( array_key_exists ( 'hello' , $a )); // TRUE
// Checking deeper array values
var_dump (isset( $a [ 'pie' ][ 'a' ])); // TRUE
var_dump (isset( $a [ 'pie' ][ 'b' ])); // FALSE
var_dump (isset( $a [ 'cake' ][ 'a' ][ 'b' ])); // FALSE
?>
Example #2 isset() on String Offsets
PHP 5.4 changes how isset() behaves when passed string offsets.
<?php
$expected_array_got_string = 'somestring' ;
var_dump (isset( $expected_array_got_string [ 'some_key' ]));
var_dump (isset( $expected_array_got_string [ 0 ]));
var_dump (isset( $expected_array_got_string [ '0' ]));
var_dump (isset( $expected_array_got_string [ 0.5 ]));
var_dump (isset( $expected_array_got_string [ '0.5' ]));
var_dump (isset( $expected_array_got_string [ '0 Mostel' ]));
?>
以上例程在PHP 5.3中的输出:
bool(true) bool(true) bool(true) bool(true) bool(true) bool(true)
以上例程在PHP 5.4中的输出:
bool(false) bool(true) bool(true) bool(true) bool(false) bool(false)
isset() 只能用于变量,因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置,可使用 defined() 函数。
Note: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。
Note:
如果使用 isset() 来检查对象无法访问的属性,如果 __isset() 方法已经定义则会调用这个重载方法。
[#1] ohcc at 163 dot com [2015-11-21 08:59:39]
When a variable is set and its values is null, isset() returns false.
You can use array_key_exists() to check whether a null value variable exists.
<?php
$wxc = null;
var_dump( isset( $wxc ) );
var_dump( array_key_exists( 'wxc', $GLOBALS ) );
?>
Output of the above example:
bool(false) bool(true)
[#2] ericg at arty-web-design dot com [2015-07-25 10:00:33]
I found something interesting while working with isset() in PHP5.5+
<?php
$a = "foo";
$b = "bar";
var_dump(isset($a, $b)); //returns true
unset($b);
var_dump(isset($a,$b)); // returns false (as expected);
...BUT...
var_dump(!isset($a,$b)); // STILL returns true!
[#3] andreasonny83 at gmail dot com [2015-05-12 11:26:48]
Here is an example with multiple parameters supplied
<?php
$var = array();
$var['val1'] = 'test';
$var['val2'] = 'on';
if ( isset( $var['val1'], $var['val2'] ) && $var['val2'] === 'on' ) {
unset( $var['val1'] );
}
print_r( $var );
?>
This will output:
Array
(
[val2] => on
)
The following code does the same calling "isset" 2 times:
<?php
$var = array();
$var['val1'] = 'test';
$var['val2'] = 'on';
if ( isset( $var['val1'] ) && isset( $var['val2'] ) && $var['val2'] === 'on' ) {
unset( $var['val1'] );
}
print_r( $var );
?>
[#4] flobee [2013-11-08 14:38:17]
KISS: array_key_exists() is often the answer, not isset()
<?php
$array['secure'] = null;
if ( isset( $array['secure'] ) ) {
// what happens here?
}?>
[#5] falkon303 at gmail dot com [2013-10-02 23:23:14]
Here is another way to check if you have any $_GET variable set.
<?php
if (sizeof($_GET) > 0)
{echo "There are $_GET variables.";}
else
{echo "There are no $_GET variables.";};
?>
Alternatively you could use the switch method.
[#6] marcio at suhdo dot com [2013-07-07 23:08:43]
//thin way to set a variable
$foo = isset($_POST['foo']) ? $_POST['foo'] : null;
[#7] uramihsayibok, gmail, com [2013-04-25 23:32:33]
Note that isset() is not recursive as of the 5.4.8 I have available here to test with: if you use it on a multidimensional array or an object it will not check isset() on each dimension as it goes.
Imagine you have a class with a normal __isset and a __get that fatals for non-existant properties. isset($object->nosuch) will behave normally but isset($object->nosuch->foo) will crash. Rather harsh IMO but still possible.
<?php
class FatalOnGet {
// pretend that the methods have implementations that actually try to do work
// in this example I only care about the worst case conditions
public function __get($name) {
echo "(getting {$name}) ";
// if property does not exist {
echo "Property does not exist!";
exit;
// }
}
public function __isset($name) {
echo "(isset {$name}?) ";
// return whether the property exists
return false;
}
}
$obj = new FatalOnGet();
// works
echo "Testing if ->nosuch exists: ";
if (isset($obj->nosuch)) echo "Yes"; else echo "No";
// fatals
echo "\nTesting if ->nosuch->foo exists: ";
if (isset($obj->nosuch->foo)) echo "Yes"; else echo "No";
// not executed
echo "\nTesting if ->irrelevant exists: ";
if (isset($obj->irrelevant)) echo "Yes"; else echo "No";
?>
Testing if ->nosuch exists: No
Testing if ->nosuch->foo exists: Property does not exist!
Uncomment the echos in the methods and you'll see exactly what happened:
Testing if ->nosuch exists: (isset nosuch?) No
Testing if ->nosuch->foo exists: (getting nosuch) Property does not exist!
On a similar note, if __get always returns but instead issues warnings or notices then those will surface.
[#8] Hayle Watson [2013-04-22 05:39:15]
<?php
return isset($nonexistentarray['foo']);
?>
Returns false without trouble (assuming $nonexistent array does not exist).
<?php
$foo = 17;
return isset($nonexistentarray[$foo]);
?>
Also returns false without trouble.
But, oddly,
<?php
return isset($nonexistentarray[$nonexistentkey]);
?>
While returning false, also triggers a notice regarding the undefined variable "$nonexistentkey".
Some thought shows that this is the right behaviour (we're testing for the existence of an array element, but we need to know which array element we're testing the existence of), but it probably isn't obvious. This implies that:
<?php
$extantarray[null] = 42;
return isset($extantarray[$nonexistentkey]);
?>
Triggers a notice and returns true.
[#9] Daniel Klein [2012-05-29 03:49:35]
How to test for a variable actually existing, including being set to null. This will prevent errors when passing to functions.
<?php
// false
var_export(
array_key_exists('myvar', get_defined_vars())
);
$myvar;
// false
var_export(
array_key_exists('myvar', get_defined_vars())
);
$myvar = null;
// true
var_export(
array_key_exists('myvar', get_defined_vars())
);
unset($myvar);
// false
var_export(
array_key_exists('myvar', get_defined_vars())
);
if (array_key_exists('myvar', get_defined_vars())) {
myfunction($myvar);
}
?>
Note: you can't turn this into a function (e.g. is_defined($myvar)) because get_defined_vars() only gets the variables in the current scope and entering a function changes the scope.
[#10] glitch dot mr at gmail dot com [2012-05-23 18:02:41]
This is very simple implementation of issetor() for PHP. It works like ?? in C#, // in Perl (it can access undefined hash keys without it nevertheless) or ? in CoffeeScript (also can access undefined hash keys too). You shouldn't use directly $_GET['something'] (it can generate E_NOTICEs in case somebody would try hacking your site), but isset($_GET['something']) ? $_GET['something'] : '' is long for many people (for so common operation). This alternative makes using superglobals easier.
<?php
function issetor(&$variable, $or = NULL) {
return $variable === NULL ? $or : $variable;
}
?>
Now you can do:
<?php
echo issetor($_GET['a']); // $_GET['a'] or NULL
echo issetor($_GET['b'], '42'); // $_GET['b'] or 42
echo issetor($_GET['c']['d']); // $_GET['c']['d'] or NULL
?>
This code doesn't generate notices in case variable doesn't exist.
[#11] david at thegallagher dot net [2012-03-09 02:20:25]
Just to reiterate on what everyone has already said before, you should not use wrapper functions for isset. Using a wrapper function will generate a Notice unless you pass the unset variable by reference, in which case it is the equivalent to writing using $var === null (which is a lot faster). Even if you do pass the variable by reference, you could still get notices using multidimensional arrays where isset() would silently return false.
[#12] qeremy [2012-03-07 15:36:01]
Simple solution for: "Fatal error: Can't use function return value in write context in ..."
<?php
function _isset($val) { return isset($val); }
?>
[#13] john at darven dot co dot uk [2011-11-14 02:37:32]
It is worth noting that in order to check for the existence of a key within an array, regardless of it's contents one should use array_key_exists() not isset().
isset() will (correctly) return false if the value of your array key is null, which may be a perfectly valid condition.
[#14] gonchalox at gmail dot com [2011-06-25 04:33:24]
Useful to check if the variable have some value...specially for GET POST variables
<?php
function isset_or(&$check, $alternate = NULL)
{
return (isset($check)) ? (empty($check) ? $alternate : $check) : $alternate;
}
function getGETPOST($var)
{
return isset_or($_GET[$var],isset_or($_POST[$var],"Empty"));
}
?>
Example
echo getGETPOST('na'); //Find the na varriabl by get and post
[#15] benallfree at gmail dot com [2011-04-21 18:21:57]
isset() returns TRUE if a value is NULL. That seems wrong to me as there is no way to distinguish between a value set to NULL and a truly undefined value.
If you have this problem inside a class, there is a fix:
<?php
class T
{
function __isset($att)
{
$props = get_object_vars($this);
return array_key_exists($att, $props);
}
}
$x = new T();
$x->foo_exists = 4;
var_dump(isset($x->foo_exists)); // TRUE
var_dump(isset($x->bar_exists)); // FALSE
?>
[EDITOR thiago NOTE: This snippet has improvements by "Paul Lashbrook"]
[#16] Cuong Huy To [2011-03-23 05:08:08]
1) Note that isset($var) doesn't distinguish the two cases when $var is undefined, or is null. Evidence is in the following code.
<?php
unset($undefined);
$null = null;
if (true === isset($undefined)){echo 'isset($undefined) === true'} else {echo 'isset($undefined) === false'); // 'isset($undefined) === false'
if (true === isset($null)){echo 'isset($null) === true'} else {echo 'isset($null) === false'); // 'isset($null) === false'
?>
2) If you want to distinguish undefined variable with a defined variable with a null value, then use array_key_exist
<?php
unset($undefined);
$null = null;
if (true !== array_key_exists('undefined', get_defined_vars())) {echo '$undefined does not exist';} else {echo '$undefined exists';} // '$undefined does not exist'
if (true === array_key_exists('null', get_defined_vars())) {echo '$null exists';} else {echo '$null does not exist';} // '$null exists'
?>
[#17] francois vespa [2010-12-22 19:21:53]
Now this is how to achieve the same effect (ie, having isset() returning true even if variable has been set to null) for objects and arrays
<?php
// array
$array=array('foo'=>null);
return isset($array['foo']) || array_key_exists('foo',$array)
? true : false ; // return true
return isset($array['inexistent']) || array_key_exists('inexistent',$array)
? true : false ; // return false
// static class
class bar
{
static $foo=null;
}
return isset(bar::$foo) || array_key_exists('foo',get_class_vars('bar'))
? true : false ; // return true
return isset(bar::$inexistent) || array_key_exists('inexistent',get_class_vars('bar'))
? true : false ; // return false
// object
class bar
{
public $foo=null;
}
$bar=new bar();
return isset($bar->foo) || array_key_exists('foo',get_object_vars($bar))
? true : false ; // return true
return isset($bar->inexistent) || array_key_exists('inexistent',get_object_vars($bar))
? true : false ; // return true
// stdClass
$bar=new stdClass;
$bar->foo=null;
return isset($bar->foo) || array_key_exists('foo',get_object_vars($bar))
? true : false ; // return true
return isset($bar->inexistent) || array_key_exists('inexistent',get_object_vars($bar))
? true : false ; // return true
?>
[#18] i [at] nemoden [dot] com [2010-06-14 23:48:19]
Simple, but very useful:
<?php
function issetOr($var, $or = false) {
return isset($var) ? $var : $or;
}
?>
Some examples:
<?php
$a = '1';
$b = '2';
echo issetOr($a,issetOr($b,3)); // 1
?>
<?php
$b = '2';
echo issetOr($a,issetOr($b,3)); // 2
?>
<?php
echo issetOr($a,issetOr($b,3)); // 3
?>
[#19] Robert dot VanDell at cbs dot com [2010-01-08 14:19:18]
Here's a nice little function that I use everywhere that'll help with setting alternate values so you don't have a bunch of situations like:
<?php
if(isset($a))
{
$b = $a;
}
else
{
$b = "default";
}
function isset_or(&$check, $alternate = NULL)
{
return (isset($check)) ? $check : $alternate;
}
// Example usage:
$first_name = isset_or($_POST['first_name'], "Empty");
$total = isset_or($row['total'], 0);
?>
[#20] Anl zselgin [2009-08-14 15:30:40]
Note: Because this is a language construct and not a function, it cannot be called using variable functions.
So why it is under "Variable handling Functions". Maybe there should be some good documentation field for language constructs.
[#21] Ashus [2008-12-08 13:05:37]
Note that array keys are case sensitive.
<?php
$ar['w'] = true;
var_dump(isset($ar['w']),
isset($ar['W']));
?>
will report:
bool(true) bool(false)
[#22] jwvdveer at gmail dot com [2008-11-10 10:29:29]
Here a short note on the function tomek wrote:
Don't use it, because it is still better to use !$var than !is($var).
Some comments on the body of the function:
<?php
function is($var)
{
if (!isset($var)) return false; # Variable is always set... Otherwise PHP would have thrown an error on call.
if ($var!==false) return true; # So, 0, NULL, and some other values may not behave like isNot? And what about the difference between a class and NULL?
return false;
}
?>
The reason why you shall not use this function:
Notice: Undefined variable: {variablename} in {file} on line {__LINE__}
It's me as plain as the nose on your face that the piece of code hasn't been tested with E_NOTICE.
So my advice in this case is: don't use the above function, but simply use !, and functions such like is_null in the situation they are made for.
[#23] tomek [2008-10-26 06:48:43]
Here's a simple function to test if the variable is set:
<?php
function is($var)
{
if (!isset($var)) return false;
if ($var!==false) return true;
return false;
}
?>
Now instead of very popular (but invalid in many situations):
if (!$var) $var=5;
you can write:
if (!is($var)) $var=5;
[#24] a dot schaffhirt at sedna-soft dot de [2008-10-12 08:01:58]
You can safely use isset to check properties and subproperties of objects directly. So instead of writing
isset($abc) && isset($abc->def) && isset($abc->def->ghi)
or in a shorter form
isset($abc, $abc->def, $abc->def->ghi)
you can just write
isset ($abc->def->ghi)
without raising any errors, warnings or notices.
Examples
<?php
$abc = (object) array("def" => 123);
var_dump(isset($abc)); // bool(true)
var_dump(isset($abc->def)); // bool(true)
var_dump(isset($abc->def->ghi)); // bool(false)
var_dump(isset($abc->def->ghi->jkl)); // bool(false)
var_dump(isset($def)); // bool(false)
var_dump(isset($def->ghi)); // bool(false)
var_dump(isset($def->ghi->jkl)); // bool(false)
var_dump($abc); // object(stdClass)#1 (1) { ["def"] => int(123) }
var_dump($abc->def); // int(123)
var_dump($abc->def->ghi); // null / E_NOTICE: Trying to get property of non-object
var_dump($abc->def->ghi->jkl); // null / E_NOTICE: Trying to get property of non-object
var_dump($def); // null / E_NOTICE: Trying to get property of non-object
var_dump($def->ghi); // null / E_NOTICE: Trying to get property of non-object
var_dump($def->ghi->jkl); // null / E_NOTICE: Trying to get property of non-object
?>
[#25] mark dot fabrizio at gmail dot com [2008-09-15 19:01:40]
I know this is probably not the recommended way to do this, but it seems to work fine for me. Instead of the normal isset check to extract variables from arrays (like $_REQUEST), you can use the @ prefix to squelch any errors.
For example, instead of:
<?php
$test = isset($_REQUEST['test']) ? $_REQUEST['test'] : null;
?>
you can use:
<?php
$test = @$_REQUEST['test'];
?>
It saves some typing, but doesn't give the opportunity to provide a default value. If 'test' is not an assigned key for $_REQUEST, the assigned value will be null.
[#26] mandos78 AT mail from google [2008-07-29 02:40:12]
Careful with this function "ifsetfor" by soapergem, passing by reference means that if, like the example $_GET['id'], the argument is an array index, it will be created in the original array (with a null value), thus causing posible trouble with the following code. At least in PHP 5.
For example:
<?php
$a = array();
print_r($a);
ifsetor($a["unsetindex"], 'default');
print_r($a);
?>
will print
Array
(
)
Array
(
[unsetindex] =>
)
Any foreach or similar will be different before and after the call.
[#27] soapergem at gmail dot com [2008-07-02 13:34:13]
It is possible to encapsulate isset() calls inside your own functions if you pass them by reference (note the ampersand in the argument list) instead of by value. A prime example would be the heavily-requested "ifsetor" function, which will return a value when it is set, otherwise a default value that the user specifies is used.
<?php
function ifsetor(&$val, $default = null)
{
return isset($val) ? $val : $default;
}
// example usage
$id = intval(ifsetor($_GET['id'], 0));
?>
[#28] soapergem at gmail dot com [2008-06-04 14:19:22]
Below a user by the name of Scott posted an isval() function; I just wanted to point out a revision to his method since it's a bit lengthy for what it does. The trick is to realize that a boolean AND clause will terminate with false as soon as it encounters anything that evaluates to false, and will skip over any remaining checks.
Instead of taking up the space to define isval(), you could just run inline commands for each variable you need to check this:
<?php
$isval = isset($_POST['var']) && !empty($_POST['var']);
?>
Also be warned that if you try to encapsulate this into a function, you might encounter problems. It's meant to stand alone.
[#29] anonymousleaf at gmail dot com [2008-02-25 10:16:28]
isset expects the variable sign first, so you can't add parentheses or anything.
<?php
$foo = 1;
if(isset(($foo))) { // Syntax error at isset((
$foo = 2;
}
?>
[#30] muratyaman at gmail dot com [2008-02-07 04:40:02]
To organize some of the frequently used functions..
<?php
function nz($arr_or_obj, $key_or_prop, $else){
$result = $else;
if(isset($arr_or_obj)){
if(is_array($arr_or_obj){
if(isset($arr_or_obj[$key_or_prop]))
$result = $arr_or_obj[$key_or_prop];
}elseif(is_object($arr_or_object))
if(isset($arr_or_obj->$key_or_prop))
$result = $arr_or_obj->$key_or_prop;
}
}
return $result;
}
function nz_int($arr_or_obj, $key_or_prop, $else){
return intval(nz($arr_or_obj, $key_or_prop, $else));
}
$my_id = nz_int($_REQUEST, 'id', 0);
if($my_id > 0){
//why?
}
?>
[#31] packard_bell_nec at hotmail dot com [2007-12-25 11:18:44]
Note: isset() only checks variables as anything else will result in a parse error. In other words, the following will not work: isset(trim($name)).
isset() is the opposite of is_null($var) , except that no warning is generated when the variable is not set.
[#32] sam b [2007-11-13 10:51:07]
Check out this ifsetor function. If $var is set, do nothing, otherwise $var = $default.
<?php
$name = ifsetor($name, 'default name') ;
function ifsetor(&$var, $default)
{
return isset($var) ? $var : $default) ;
}
?>
[#33] contact at scottbyrns dot com [2007-11-07 17:51:36]
If you have for example a variable in your URL say url.php?var= and some one types in %00 the variable will pass isset. For post and get variables I wrote this function to filter out varables that are set but empty.
function isval($inp){
if(isset($inp)){
$len = strlen($inp);
if($len > 0){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
[#34] petruzanauticoyahoo?com!ar [2007-10-14 11:22:36]
I've come up with a little not-so-clean but useful function to avoid checking if a variable is set before reading its value, specially useful for $_REQUEST and the like:
<?php
function toLocal( $source, &$dest, $default = null )
{
if( isset( $source ) )
$dest = $source;
else
$dest = $default;
}
?>
and then call it this way:
<?php
@toLocal( $_REQUEST['item_id'], $item_id, 0 );
?>
It checks wether the variable is set, copies it to a local variable, and if it wasn't set, it assigns the new variable a default value, all in one line, preventing you to have to always check for isset() before trying to read its value.
Gotta call it with @ because if the variable is not set, then trying to pass it as an argument will yield a warning.
Petruza.
[#35] talbutt(at)mail(dot)med(dot)upenn(edu) [2007-08-13 08:30:48]
In PHP 5.2.3, really returns true if the variable is set to null.
[#36] black__ray at myway dot com [2007-07-03 04:40:41]
if(isset($_POST['in_qu']))
{
include("qanda/in_qu.php");
$content.=$message;
include("qanda/view_qanda.php");
}
elseif(isset($_GET['rq']))
{
include("qanda/add_answer.php");
}
elseif(isset($_POST['add_answer']))
{
include("qanda/in_an.php");
$content.=$message;
include("qanda/view_qanda.php");
}
elseif($_GET['act']== 'v_qanda' && !(isset($_GET['rq'])))
{
include("qanda/view_qanda.php");
}
function print_r_level($data, $level = 5)
{
static $innerLevel = 1;
static $tabLevel = 1;
static $cache = array();
$self = __FUNCTION__;
$type = gettype($data);
$tabs = str_repeat(' ', $tabLevel);
$quoteTabes = str_repeat(' ', $tabLevel - 1);
$recrusiveType = array('object', 'array');
// Recrusive
if (in_array($type, $recrusiveType))
{
// If type is object, try to get properties by Reflection.
if ($type == 'object')
{
if (in_array($data, $cache))
{
return "\n{$quoteTabes}*RECURSION*\n";
}
// Cache the data
$cache[] = $data;
$output = get_class($data) . ' ' . ucfirst($type);
$ref = new \ReflectionObject($data);
$properties = $ref->getProperties();
$elements = array();
foreach ($properties as $property)
{
$property->setAccessible(true);
$pType = $property->getName();
if ($property->isProtected())
{
$pType .= ":protected";
}
elseif ($property->isPrivate())
{
$pType .= ":" . $property->class . ":private";
}
if ($property->isStatic())
{
$pType .= ":static";
}
$elements[$pType] = $property->getValue($data);
}
}
// If type is array, just retun it's value.
elseif ($type == 'array')
{
$output = ucfirst($type);
$elements = $data;
}
// Start dumping datas
if ($level == 0 || $innerLevel < $level)
{
// Start recrusive print
$output .= "\n{$quoteTabes}(";
foreach ($elements as $key => $element)
{
$output .= "\n{$tabs}[{$key}] => ";
// Increment level
$tabLevel = $tabLevel + 2;
$innerLevel++;
$output .= in_array(gettype($element), $recrusiveType) ? $self($element, $level) : $element;
// Decrement level
$tabLevel = $tabLevel - 2;
$innerLevel--;
}
$output .= "\n{$quoteTabes})\n";
}
else
{
$output .= "\n{$quoteTabes}*MAX LEVEL*\n";
}
}
// Clean cache
if($innerLevel == 1)
{
$cache = array();
}
return $output;
}// End function
// TEST ------------------------------------
class testClass
{
protected $a = 'aaa';
private $b = 'bbb';
public $c = array(1, 2, ['a', 'b', 'c'], 4);
static public $d = 'ddd';
static protected $e = 'eee';
}
$test = new testClass;
$test->testClass = $test;
echo '<pre>' . print_r_level($test, 3) . '</pre>';
?>
will output
-------------------------------------------------------------
testClass Object
(
[a:protected] => aaa
[b:testClass:private] => bbb
[c] => Array
(
[0] => 1
[1] => 2
[2] => Array
*MAX LEVEL*
[3] => 4
)
[d:static] => ddd
[e:protected:static] => eee
[testClass] =>
*RECURSION*
)
[#6] alex uses khimich.org [2013-10-20 21:43:27]
Sometimes, when page is called by ajax and you're not actually feeling convenient to see output of debugging, you may log it in file like shown below:
<?php
// Log superglobals
$g=print_r($_GET,true);
$p=print_r($_POST,true);
$f=print_r($_FILES,true);
$s=print_r($_SESSION,true);
$txt='';
$txt.="/n".'GET: '.$g;
$txt.="/n".'POST: '.$p;
$txt.="/n".'FILES: '.$f;
$txt.="/n".'SESSION: '.$s;
file_put_contents('requests.txt',$txt);
?>
[#7] bginfos at web dot de [2013-10-06 11:40:23]
function : debug_print
<?php
// --------------------------------------------------------------
function debug_print($var, $nfo='DEBUG', $htm=false, $ret=false) {
$var_str = print_r($var, true);
if ($htm !== false) { $var_str = htmlentities($var_str); }
$outstr = '';
$outstr = '<p>--------- <strong>'.$nfo.'</strong> ---------</p>'."\n";
$outstr .= '<pre style="margin:18px 4px; padding:6px; text-align:left; background:#DEDEDE; color:#000099;">'."\n";
$outstr .= $var_str."\n";
$outstr .= '</pre>'."\n";
if ($ret !== false) { $result = $outstr; }
else { print $outstr; $result = true; }
return $result;
}
// --------------------------------------------------------------
?>
usage:
<?php
// --------------------------------------------
$data = array('some', 'example', 'test');
// --- direct output ---
debug_print($data);
// --- returned output ---
$debug_str = debug_print($data, 'some text', false, true);
print $debug_str;
// --------------------------------------------
?>
[#8] preda dot vlad at yahoo dot com [2013-03-22 09:40:42]
print_r(), just like var_dump() does NOT cast an object, not even if it has a __toString() method - which is normal.
<?php
class A {
public function __toString() {
return 'In class A';
}
}
$a = new A;
echo $a; // In class A
print_r($a); // A Object()
// you can simulate the echo by casting it manually
print_r((string)$a); // In class A
[#9] ReanimationXP at g m a i l dot com [2012-07-22 12:49:15]
If you're like me and just want an exact version of print_r() except formatted to HTML without a bunch of bs, here you go.
The output is identical to print_r() but renders in HTML.
<?php
// Displays a multi-dimensional array as a HTML unordered lists.
function displayTree($array) {
$newline = "<br>";
foreach($array as $key => $value) { //cycle through each item in the array as key => value pairs
if (is_array($value) || is_object($value)) { //if the VALUE is an array, then
//call it out as such, surround with brackets, and recursively call displayTree.
$value = "Array()" . $newline . "(<ul>" . displayTree($value) . "</ul>)" . $newline;
}
//if value isn't an array, it must be a string. output its' key and value.
$output .= "[$key] => " . $value . $newline;
}
return $output;
}
?>
[#10] henzeberkheij at gmail dot com [2012-01-28 15:10:31]
print_r is used for debug purposes. Yet I had some classes where I just wanted the values coming out of the database, not all the other crap. thus i wrote the following function. If your class has an toArray function, that one will be called otherwise it will return the object as is. print_neat_classes_r is the function that should be called!
<?php
print_neat_classes_r($array, $return=false){
return print_r(self::neat_class_print_r($array), $return);
}
function do_print_r($array, $return=false){
if(is_object($array) && method_exists($array, 'toArray')){
return $array->toArray();
}else if(is_array($array)){
foreach($array as $key=>$obj){
$array[$key] = self::do_print_r($obj, $return);
}
return $array;
}else{
return $array;
}
}
?>
[#11] eithed [2011-10-21 02:25:49]
Bear in mind that print_r actually reserves some memory to do something - so, for example thing like:
<?php
function shutdown_handler()
{
file_put_contents($_SERVER['DOCUMENT_ROOT']."/log.txt", print_r($_REQUEST, true));
}
ini_set('memory_limit', '1M');
register_shutdown_function("shutdown_handler");
$array = array();
while(true)
$array[] = new stdClass();
?>
will just not work. Try using var_export, and presto, everything is fine.
[#12] jwood at JPL dot gov (w/ Bug fixed) [2011-08-10 16:04:10]
<?php
// Displays a multi-dimensional array as a HTML List (Tree structure).
function displayTree($var) {
$newline = "\n";
foreach($var as $key => $value) {
if (is_array($value) || is_object($value)) {
$value = $newline . "<ul>" . displayTree($value) . "</ul>";
}
if (is_array($var)) {
if (!stripos($value, "<li class=")) {
$output .= "<li class=\"file\">" . $value . "</li>" . $newline;
}
else {
$output .= $value . $newline;
}
}
else { // is_object
if (!stripos($value, "<li class=")) {
$value = "<ul><li class=\"file\">" . $value . "</li></ul>" . $newline;
}
$output .= "<li class=\"folder\">" . $key . $value . "</li>" . $newline;
}
}
return $output;
}
?>
///////////////////
Also need to add this to your style sheet (and get the necessary images...):
li.folder
{
list-style-image: url(../img/folder.gif);
}
li.file
{
list-style-image: url(../img/file.gif);
}
///////////////////
Example Usage:
<?php
...
echo "<ul>";
echo displayTree($array);
echo "</ul>";
?>
[#13] Robert Heine (joomla-jquery-internet.de) [2011-04-18 07:09:55]
Since i use print_r for debugging a lot, i always use the following function in my scripts, which makes life a lot easier :-)
<?php
if (!function_exists("preprint")) {
function preprint($s, $return=false) {
$x = "<pre>";
$x .= print_r($s, 1);
$x .= "</pre>";
if ($return) return $x;
else print $x;
}
}
?>
-------------------
USAGE: preprint($x); <- where $x = array().
-------------------
The optional 2. parameter can be set to "true", so the html-code is returned.
Have fun,
[#14] machuidel [2011-02-03 04:01:05]
The following will output an array in a PHP parsable format:
<?php
function serialize_array(&$array, $root = '$root', $depth = 0)
{
$items = array();
foreach($array as $key => &$value)
{
if(is_array($value))
{
serialize_array($value, $root . '[\'' . $key . '\']', $depth + 1);
}
else
{
$items[$key] = $value;
}
}
if(count($items) > 0)
{
echo $root . ' = array(';
$prefix = '';
foreach($items as $key => &$value)
{
echo $prefix . '\'' . $key . '\' => \'' . addslashes($value) . '\'';
$prefix = ', ';
}
echo ');' . "\n";
}
}
?>
[#15] Alexander [2010-03-19 05:20:36]
A simple function to send the output of print_r to firebug.
The script creates a dummy console object with a log method for when firebug is disabled/not available.
<?php
function debug ($data) {
echo "<script>\r\n//<![CDATA[\r\nif(!console){var console={log:function(){}}}";
$output = explode("\n", print_r($data, true));
foreach ($output as $line) {
if (trim($line)) {
$line = addslashes($line);
echo "console.log(\"{$line}\");";
}
}
echo "\r\n//]]>\r\n</script>";
}
?>
[#16] liamtoh6 at hotmail dot com [2010-02-03 10:01:42]
I add this function to the global scope on just about every project I do, it makes reading the output of print_r() in a browser infinitely easier.
<?php
function print_r2($val){
echo '<pre>';
print_r($val);
echo '</pre>';
}
?>
It also makes sense in some cases to add an if statement to only display the output in certain scenarios, such as:
if(debug==true)
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1')
[#17] jeremy dot ruten at gmail dot com [2009-09-26 19:16:03]
Here's an array_depth() function that calculates the depth of an array using the indentation in the output of print_r():
<?php
function array_depth($array) {
$max_indentation = 1;
$array_str = print_r($array, true);
$lines = explode("\n", $array_str);
foreach ($lines as $line) {
$indentation = (strlen($line) - strlen(ltrim($line))) / 4;
if ($indentation > $max_indentation) {
$max_indentation = $indentation;
}
}
return ceil(($max_indentation - 1) / 2) + 1;
}
?>
It's better than writing a recursive function to do the same thing, as print_r() handles the problem of infinitely-deep arrays for you quite nicely.
[#18] Matt [2009-09-14 12:53:03]
Here is another version that parses the print_r() output. I tried the one posted, but I had difficulties with it. I believe it has a problem with nested arrays. This handles nested arrays without issue as far as I can tell.
<?php
function print_r_reverse($in) {
$lines = explode("\n", trim($in));
if (trim($lines[0]) != 'Array') {
// bottomed out to something that isn't an array
return $in;
} else {
// this is an array, lets parse it
if (preg_match("/(\s{5,})\(/", $lines[1], $match)) {
// this is a tested array/recursive call to this function
// take a set of spaces off the beginning
$spaces = $match[1];
$spaces_length = strlen($spaces);
$lines_total = count($lines);
for ($i = 0; $i < $lines_total; $i++) {
if (substr($lines[$i], 0, $spaces_length) == $spaces) {
$lines[$i] = substr($lines[$i], $spaces_length);
}
}
}
array_shift($lines); // Array
array_shift($lines); // (
array_pop($lines); // )
$in = implode("\n", $lines);
// make sure we only match stuff with 4 preceding spaces (stuff for this array and not a nested one)
preg_match_all("/^\s{4}\[(.+?)\] \=\> /m", $in, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
$pos = array();
$previous_key = '';
$in_length = strlen($in);
// store the following in $pos:
// array with key = key of the parsed array's item
// value = array(start position in $in, $end position in $in)
foreach ($matches as $match) {
$key = $match[1][0];
$start = $match[0][1] + strlen($match[0][0]);
$pos[$key] = array($start, $in_length);
if ($previous_key != '') $pos[$previous_key][1] = $match[0][1] - 1;
$previous_key = $key;
}
$ret = array();
foreach ($pos as $key => $where) {
// recursively see if the parsed out value is an array too
$ret[$key] = print_r_reverse(substr($in, $where[0], $where[1] - $where[0]));
}
return $ret;
}
}
?>
[#19] Federico Bricker [2009-06-29 16:02:29]
Here is a nice version of print_r that prints things with colors and tables.
I've called it print_nice
<?php
function print_nice($elem,$max_level=10,$print_nice_stack=array()){
if(is_array($elem) || is_object($elem)){
if(in_array(&$elem,$print_nice_stack,true)){
echo "<font color=red>RECURSION</font>";
return;
}
$print_nice_stack[]=&$elem;
if($max_level<1){
echo "<font color=red>nivel maximo alcanzado</font>";
return;
}
$max_level--;
echo "<table border=1 cellspacing=0 cellpadding=3 width=100%>";
if(is_array($elem)){
echo '<tr><td colspan=2 style="background-color:#333333;"><strong><font color=white>ARRAY</font></strong></td></tr>';
}else{
echo '<tr><td colspan=2 style="background-color:#333333;"><strong>';
echo '<font color=white>OBJECT Type: '.get_class($elem).'</font></strong></td></tr>';
}
$color=0;
foreach($elem as $k => $v){
if($max_level%2){
$rgb=($color++%2)?"#888888":"#BBBBBB";
}else{
$rgb=($color++%2)?"#8888BB":"#BBBBFF";
}
echo '<tr><td valign="top" style="width:40px;background-color:'.$rgb.';">';
echo '<strong>'.$k."</strong></td><td>";
print_nice($v,$max_level,$print_nice_stack);
echo "</td></tr>";
}
echo "</table>";
return;
}
if($elem === null){
echo "<font color=green>NULL</font>";
}elseif($elem === 0){
echo "0";
}elseif($elem === true){
echo "<font color=green>TRUE</font>";
}elseif($elem === false){
echo "<font color=green>FALSE</font>";
}elseif($elem === ""){
echo "<font color=green>EMPTY STRING</font>";
}else{
echo str_replace("\n","<strong><font color=red>*</font></strong><br>\n",$elem);
}
}
?>
[#20] Bob [2009-05-08 03:19:02]
Here is a function that formats the output of print_r as a expandable/collapsable tree list using HTML and JavaScript.
<?php
function print_r_tree($data)
{
// capture the output of print_r
$out = print_r($data, true);
// replace something like '[element] => <newline> (' with <a href="javascript:toggleDisplay('...');">...</a><div id="..." style="display: none;">
$out = preg_replace('/([ \t]*)(\[[^\]]+\][ \t]*\=\>[ \t]*[a-z0-9 \t_]+)\n[ \t]*\(/iUe',"'\\1<a href=\"javascript:toggleDisplay(\''.(\$id = substr(md5(rand().'\\0'), 0, 7)).'\');\">\\2</a><div id=\"'.\$id.'\" style=\"display: none;\">'", $out);
// replace ')' on its own on a new line (surrounded by whitespace is ok) with '</div>
$out = preg_replace('/^\s*\)\s*$/m', '</div>', $out);
// print the javascript function toggleDisplay() and then the transformed output
echo '<script language="Javascript">function toggleDisplay(id) { document.getElementById(id).style.display = (document.getElementById(id).style.display == "block") ? "none" : "block"; }</script>'."\n$out";
}
?>
Pass it a multidimensional array or object and each sub-array/object will be hidden and replaced by a html link that will toggle its display on and off.
Its quick and dirty, but great for debugging the contents of large arrays and objects.
Note: You'll want to surround the output with <pre></pre>
[#21] sebasg37 at gmail dot com [2009-01-25 21:35:58]
If you have to catch the output without showing it at all at first (for example, if you want to append the print_r output to a file), you can do this:
<?php
ob_start();
print_r( $some_array );
$output = ob_get_clean();
// if you want to append the print_r output of $some_array to, let's say, log.txt:
file_put_contents( 'log.txt', file_get_contents( 'log.txt' ) . $output )
?>
[#22] afisher8 at cox dot net [2008-12-17 08:53:47]
I use this all the time when debugging objects, but when you have a very large object with big arrays of sub-objects, it's easy to get overwhelmed with the large amount of output....sometimes you don't want to see absolutely every sub-object.
I made this function to debug objects while "hiding" sub-objects of certain types. This also color codes the output for a more readable printout.
<?php
function wtf($var, $arrayOfObjectsToHide=null, $fontSize=11)
{
$text = print_r($var, true);
if (is_array($arrayOfObjectsToHide)) {
foreach ($arrayOfObjectsToHide as $objectName) {
$searchPattern = '#('.$objectName.' Object\n(\s+)\().*?\n\2\)\n#s';
$replace = "$1<span style=\"color: #FF9900;\">--> HIDDEN - courtesy of wtf() <--</span>)";
$text = preg_replace($searchPattern, $replace, $text);
}
}
// color code objects
$text = preg_replace('#(\w+)(\s+Object\s+\()#s', '<span style="color: #079700;">$1</span>$2', $text);
// color code object properties
$text = preg_replace('#\[(\w+)\:(public|private|protected)\]#', '[<span style="color: #000099;">$1</span>:<span style="color: #009999;">$2</span>]', $text);
echo '<pre style="font-size: '.$fontSize.'px; line-height: '.$fontSize.'px;">'.$text.'</pre>';
}
// example usage:
wtf($myBigObject, array('NameOfObjectToHide_1', 'NameOfObjectToHide_2'));
?>
[#23] vista_ at live dot se [2008-12-04 08:31:42]
Do you think it is difficult to see what print_r() returns?
<?php
echo '<pre>';
print_r($array);
echo '</pre>';
?>
And if you have to write this many times in a page, use this:
<?php
function preint_r($array)
{
echo '<pre>';
print_r($array);
echo '</pre>';
}
?>
[#24] kurt krueckeberg [2008-10-28 10:53:19]
This is an alternative for printing arrays. It bolds array values.
<?php
function print_array(&$a, $str = "")
{
if ($str[0]) {
echo "$str =";
}
echo ' array( ';
foreach ($a as $k => $v) {
echo "[$k]".' => ';
if (is_array($v)) {
print_array($v);
}
else {
echo "<strong>$a[$k]</strong> ";
}
}
echo ') ';
}
$a1 = array ("apples", "oranges", "pears");
$a2 = array ("potatos", "green beans", "squash");
$a3 = array ("euros", "dollars", "pesos", "dinars");
$test = range(1, 9);
array_push($test, array ("fruit" => $a1, "vegies" => $a2, "money" => $a3));
print_array($test, "test");
?>
[#25] schizo do not spamme duckie at gmail dot com [2008-10-07 05:00:13]
my take on the highlighted markupped debug function:
<?php
function print_array($var)
{
$input =var_export($var,true);
$input = preg_replace("! => \n\W+ array \(!Uims", " => Array ( ", $input);
$input = preg_replace("!array \(\W+\),!Uims", "Array ( ),", $input);
return("<pre>".str_replace('><?', '>', highlight_string('<'.'?'.$input, true))."</pre>");
}
?>
[#26] brenden at beagleproductions dot com [2008-08-28 13:58:03]
Many developers have submitted bugs to the PHP development team with regards to print_r showing protected and private properties of objects (PHP 5). This is not a bug; sensitive information (ex. database connection object) should be encapsulated within a private member function of your class.
[#27] admin at swivelgames dot com [2008-08-17 13:44:23]
I was having problems using print_r because I didn't like the fact that if tags where included in the array it would still be parsed by the browsers.
Heres a simple fix for anyone who is having the same problem as I did. This will output your text properly for viewing through the browser instead of the browser's "view source" or CLI.
Script:
<?php
$MyArray[0]="<div align='center'>My Text</div>";
echo "<pre>".htmlspecialchars(print_r($MyArray,true))."</pre>";
?>
Output:
<pre>Array
(
[0] => <div align='center'>My Text</div>
)
</pre>
[#28] Anonymous [2008-06-28 13:21:52]
I have written a nice debugging function.
This function handles arrays beautifully.
<?php
//Debug variables, $i and $k are for recursive use
function DebugDisplayVar($input, $name = "Debug", $i = "0", $k = array("Error")){
if(is_array($input))
{ foreach ($input as $i => $value){
$temp = $k;
$temp[] = $i;
DebugDisplayVar($value, $name, $i, $temp);}
}else{//if not array
echo "$".$name;//[$k]
foreach ($k as $i => $value){
if($value !=="Error"){echo "[$value]";}
}
echo " = $input<br>";
} }
//outputs
Debug[0] = value
Debug[1] = another value
ect...
?>
[#29] janci [2008-05-13 02:49:32]
You cannot use print_r(), var_dump() nor var_export() to get static member variables of a class. However, in PHP5 you can use Reflection classes for this:
<?php
$reflection = new ReflectionClass('Static');
print_r($reflection->getStaticProperties());
?>
[#30] tylmann at corvent dot ch [2008-03-28 02:07:19]
There is a library to create nice output of variables, arrays, hash-tables and even objects. It is great for developing/debugging and looks very much better than any print_r output.
Usage:
<?php
debug::show($myVar, 'caption');
?>
You can download it for free at http://sourceforge.net/projects/phpcorestdfuncs
For an example take a look at http://demo.corvent.ch/stdfuncs/
[#31] helpful at maybe dot com [2008-03-06 20:13:41]
Another slight modification to the previous post to allow for empty array elements
added the following lines after the first preg_match block
<?php
} else if ($expecting == 2 && preg_match('/^\[(.+?)\] \=\>$/', $trim, $matches)) { // array element
// the array element is blank
list ($fullMatch, $key) = $matches;
$topArray[$key] = $element;
}
?>
[#32] anon at anon dot com [2008-02-29 10:30:33]
A slight modification to the previous post to allow for arrays containing mutli line strings. haven't fully tested it with everything, but seems to work great for the stuff i've done so far.
<?php
function print_r_reverse(&$output)
{
$expecting = 0; // 0=nothing in particular, 1=array open paren '(', 2=array element or close paren ')'
$lines = explode("\n", $output);
$result = null;
$topArray = null;
$arrayStack = array();
$matches = null;
while (!empty($lines) && $result === null)
{
$line = array_shift($lines);
$trim = trim($line);
if ($trim == 'Array')
{
if ($expecting == 0)
{
$topArray = array();
$expecting = 1;
}
else
{
trigger_error("Unknown array.");
}
}
else if ($expecting == 1 && $trim == '(')
{
$expecting = 2;
}
else if ($expecting == 2 && preg_match('/^\[(.+?)\] \=\> (.+)$/', $trim, $matches)) // array element
{
list ($fullMatch, $key, $element) = $matches;
if (trim($element) == 'Array')
{
$topArray[$key] = array();
$newTopArray =& $topArray[$key];
$arrayStack[] =& $topArray;
$topArray =& $newTopArray;
$expecting = 1;
}
else
{
$topArray[$key] = $element;
}
}
else if ($expecting == 2 && $trim == ')') // end current array
{
if (empty($arrayStack))
{
$result = $topArray;
}
else // pop into parent array
{
// safe array pop
$keys = array_keys($arrayStack);
$lastKey = array_pop($keys);
$temp =& $arrayStack[$lastKey];
unset($arrayStack[$lastKey]);
$topArray =& $temp;
}
}
// Added this to allow for multi line strings.
else if (!empty($trim) && $expecting == 2)
{
// Expecting close parent or element, but got just a string
$topArray[$key] .= "\n".$line;
}
else if (!empty($trim))
{
$result = $line;
}
}
$output = implode(n, $lines);
return $result;
}
function print_r_reverse_multiple($output)
{
$result = array();
while (($reverse = print_r_reverse($output)) !== NULL)
{
$result[] = $reverse;
}
return $result;
}
$output = '
Array
(
[a] => apple
[b] => banana
[c] => Array
(
[0] => x
[1] => y
[2] => z
[3] => Array
(
[nest] => yes
[nest2] => Array
(
[nest] => some more
asffjaskkd
)
[nest3] => o rly?
)
)
)
some extra stuff
';
var_dump(print_r_reverse($output), $output);
?>
This should output
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
array(4) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
[2]=>
string(1) "z"
[3]=>
array(3) {
["nest"]=>
string(3) "yes"
["nest2"]=>
array(1) {
["nest"]=>
string(40) "some more
asffjaskkd"
}
["nest3"]=>
string(6) "o rly?"
}
}
}
string(18) "nsome extra stuffn"
Added:
else if (!empty($trim) && $expecting == 2)
{
// Expecting close parent or element, but got just a string
$topArray[$key] .= "\n".$line;
}
[#33] ario at mail dot utexas dot [education - 3 letters] [2008-02-19 12:34:51]
This is a better print_r reverse algorithm, that works with arbitrary nested arrays. Anything else it treats as strings. The second function allows you to take a string with multiple print_r results concatenated, and returns the result of parsing each of them.
<?php
function print_r_reverse(&$output)
{
$expecting = 0; // 0=nothing in particular, 1=array open paren '(', 2=array element or close paren ')'
$lines = explode("\n", $output);
$result = null;
$topArray = null;
$arrayStack = array();
$matches = null;
while (!empty($lines) && $result === null)
{
$line = array_shift($lines);
$trim = trim($line);
if ($trim == 'Array')
{
if ($expecting == 0)
{
$topArray = array();
$expecting = 1;
}
else
{
trigger_error("Unknown array.");
}
}
else if ($expecting == 1 && $trim == '(')
{
$expecting = 2;
}
else if ($expecting == 2 && preg_match('/^\[(.+?)\] \=\> (.+)$/', $trim, $matches)) // array element
{
list ($fullMatch, $key, $element) = $matches;
if (trim($element) == 'Array')
{
$topArray[$key] = array();
$newTopArray =& $topArray[$key];
$arrayStack[] =& $topArray;
$topArray =& $newTopArray;
$expecting = 1;
}
else
{
$topArray[$key] = $element;
}
}
else if ($expecting == 2 && $trim == ')') // end current array
{
if (empty($arrayStack))
{
$result = $topArray;
}
else // pop into parent array
{
// safe array pop
$keys = array_keys($arrayStack);
$lastKey = array_pop($keys);
$temp =& $arrayStack[$lastKey];
unset($arrayStack[$lastKey]);
$topArray =& $temp;
}
}
else if (!empty($trim))
{
$result = $line;
}
}
$output = implode(n, $lines);
return $result;
}
function print_r_reverse_multiple($output)
{
$result = array();
while (($reverse = print_r_reverse($output)) !== NULL)
{
$result[] = $reverse;
}
return $result;
}
$output = '
Array
(
[a] => apple
[b] => banana
[c] => Array
(
[0] => x
[1] => y
[2] => z
[3] => Array
(
[nest] => yes
[nest2] => Array
(
[nest] => some more
)
[nest3] => o rly?
)
)
)
some extra stuff
';
var_dump(print_r_reverse($output), $output);
?>
The above example will output:
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
array(4) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
[2]=>
string(1) "z"
[3]=>
array(3) {
["nest"]=>
string(3) "yes"
["nest2"]=>
array(1) {
["nest"]=>
string(9) "some more"
}
["nest3"]=>
string(6) "o rly?"
}
}
}
string(20) "
some extra stuff
"
[#34] Kokos [2008-01-31 04:52:55]
A simple function that will output an array more easily to read than print_r();
<?php
function echo_array($array,$return_me=false){
if(is_array($array) == false){
$return = "The provided variable is not an array.";
}else{
foreach($array as $name=>$value){
if(is_array($value)){
$return .= "";
$return .= "['<b>$name</b>'] {<div style='margin-left:10px;'>\n";
$return .= echo_array($value,true);
$return .= "</div>}";
$return .= "\n\n";
}else{
if(is_string($value)){
$value = "\"$value\"";
}
$return .= "['<b>$name</b>'] = $value\n\n";
}
}
}
if($return_me == true){
return $return;
}else{
echo "<pre>".$return."</pre>";
}
}
?>
[#35] bart at mediawave dot nl [2007-10-30 16:27:05]
Here's a PHP version of print_r which can be tailored to your needs. Shows protected and private properties of objects and detects recursion (for objects only!). Usage:
void u_print_r ( mixed $expression [, array $ignore] )
Use the $ignore parameter to provide an array of property names that shouldn't be followed recursively.
<?php
function u_print_r($subject, $ignore = array(), $depth = 1, $refChain = array())
{
if ($depth > 20) return;
if (is_object($subject)) {
foreach ($refChain as $refVal)
if ($refVal === $subject) {
echo "*RECURSION*\n";
return;
}
array_push($refChain, $subject);
echo get_class($subject) . " Object ( \n";
$subject = (array) $subject;
foreach ($subject as $key => $val)
if (is_array($ignore) && !in_array($key, $ignore, 1)) {
echo str_repeat(" ", $depth * 4) . '[';
if ($key{0} == "\0") {
$keyParts = explode("\0", $key);
echo $keyParts[2] . (($keyParts[1] == '*') ? ':protected' : ':private');
} else
echo $key;
echo '] => ';
u_print_r($val, $ignore, $depth + 1, $refChain);
}
echo str_repeat(" ", ($depth - 1) * 4) . ")\n";
array_pop($refChain);
} elseif (is_array($subject)) {
echo "Array ( \n";
foreach ($subject as $key => $val)
if (is_array($ignore) && !in_array($key, $ignore, 1)) {
echo str_repeat(" ", $depth * 4) . '[' . $key . '] => ';
u_print_r($val, $ignore, $depth + 1, $refChain);
}
echo str_repeat(" ", ($depth - 1) * 4) . ")\n";
} else
echo $subject . "\n";
}
?>
Example:
<?php
class test {
public $var1 = 'a';
protected $var2 = 'b';
private $var3 = 'c';
protected $array = array('x', 'y', 'z');
}
$test = new test();
$test->recursiveRef = $test;
$test->anotherRecursiveRef->recursiveRef = $test;
$test->dont->follow = 'me';
u_print_r($test, array('dont'));
?>
Will produce:
test Object (
[var1] => a
[var2:protected] => b
[var3:private] => c
[array:protected] => Array (
[0] => x
[1] => y
[2] => z
)
[recursiveRef] => *RECURSION*
[anotherRecursiveRef] => stdClass Object (
[recursiveRef] => *RECURSION*
)
)
[#36] php at deboom dot biz [2007-09-21 05:17:33]
If you need to import an print_R output back to an array you could use this.
This could also be (ab)used to convert a object into a array...
<?php
function object2array($printr) {
$newarray = array();
$a[0] = &$newarray;
if (preg_match_all('/^\s+\[(\w+).*\] => (.*)\n/m', $printr, $match)) {
foreach ($match[0] as $key => $value) {
(int)$tabs = substr_count(substr($value, 0, strpos($value, "[")), " ");
if ($match[2][$key] == 'Array' || substr($match[2][$key], -6) == 'Object') {
$a[$tabs+1] = &$a[$tabs][$match[1][$key]];
}
else {
$a[$tabs][$match[1][$key]] = $match[2][$key];
}
}
}
return $newarray;
}
?>
[#37] motin at demomusic dot nu [2007-06-19 16:01:09]
This works around the hacky nature of print_r in return mode (using output buffering for the return mode to work is hacky...):
<?php
function obsafe_print_r($var, $return = false, $html = false, $level = 0) {
$spaces = "";
$space = $html ? " " : " ";
$newline = $html ? "<br />" : "\n";
for ($i = 1; $i <= 6; $i++) {
$spaces .= $space;
}
$tabs = $spaces;
for ($i = 1; $i <= $level; $i++) {
$tabs .= $spaces;
}
if (is_array($var)) {
$title = "Array";
} elseif (is_object($var)) {
$title = get_class($var)." Object";
}
$output = $title . $newline . $newline;
foreach($var as $key => $value) {
if (is_array($value) || is_object($value)) {
$level++;
$value = obsafe_print_r($value, true, $html, $level);
$level--;
}
$output .= $tabs . "[" . $key . "] => " . $value . $newline;
}
if ($return) return $output;
else echo $output;
}
?>
Built on a function earlier posted in these comments as stated in the Doc comment. Cheers! /Fredrik (Motin)
[#38] mrasnika at users dot sourceforge dot net [2007-04-26 11:30:39]
We can all agree that print_r() output is very spartan looking. The debug data needs to be organized better, and presented in a graceful way. In the era of Web 2.0 it is somewhat strange to use plain text to dump information. A DHTML powered informatiion dumping tool will be quite better - like the the open-source alternative of print_r(); -- Krumo (http://krumo.sourceforge.net).
It renders the output using DHTML and collapsible nodes, it's layout is "skinable" and you can change it to fit your aesthetic taste. Krumo makes the output "human-readable" for real :) Plus it is compliant with both PHP4 and PHP5. Plus it detects "reference recursion". Plus you can use it to dump all various sort of data like debug back-traces, the superglobals ($_SERVER, $_ENV, $_REQUEST, $_COOKIE, $_GET, $_POST, $_SESSION), all the included files, all the declared classes, all the declared constants, all your PHP settings, all your php.ini values (if it is readable), all the loaded extensions, all the HTTP request headers, all the declared interfaces (for PHP5), all the file paths from INCLUDE_PATH, all the values of any particular INI file. Additionally it is designed to be easy to use - for example you can disable all the Krumo dumps instead of cleaning your code out of all print_r()'s and var_dump()'s. Anyway, if you check the site (http://krumo.sourceforge.net), you can found a lot of examples, demonstrations, documentation and all sort of helpful information.
[#39] Enthusiastic PHPers [2007-03-22 12:03:44]
We had an interesting problem dumping an object that
contained embedded HTML. The application makes use
of buffer manipulation functions, so print_r's 2nd argument
wasn't helpful. Here is how we solved the problem:
$object = new ObjectContainingHTML();
$savedbuffercontents = ob_get_clean();
print_r($object);
$print_r_output = ob_get_clean();
ob_start();
echo $savedbuffercontents;
echo htmlentities($print_r_output);
[#40] Matthew Ruivo (mruivo at gmail) [2007-02-22 22:47:40]
For those of you needing to print an array within a buffer callback function, I've created this quick function. It simply returns the array as a readable string rather than printing it. You can even choose whether to return it in normal text-mode or HTML. It's recursive, so multi-dimensial arrays are supported. I hope someone finds this useful!
<?php
function return_array($array, $html = false, $level = 0) {
$space = $html ? " " : " ";
$newline = $html ? "<br />" : "\n";
for ($i = 1; $i <= 6; $i++) {
$spaces .= $space;
}
$tabs = $spaces;
for ($i = 1; $i <= $level; $i++) {
$tabs .= $spaces;
}
$output = "Array" . $newline . $newline;
foreach($array as $key => $value) {
if (is_array($value)) {
$level++;
$value = return_array($value, $html, $level);
$level--;
}
$output .= $tabs . "[" . $key . "] => " . $value . $newline;
}
return $output;
}
?>
[#41] markus (at) maxxmaster (dot) org [2007-01-17 06:11:19]
i've been using a similar idea like Sawey's for quite a long time,
but was always disappointed that you don't see the name of the
variable passed to the function (eg calling it many times, you don't
know which value was provided by a certain variable at a certain time).
so i combined sawey's idea with one found on php.net to solve that problem.
for shellscripting the function only uses <pre>-tags when called in the web.
<?php
function my_r(&$var, $scope=false, $label=false){
if (is_string($scope) && $label==false) $label=$scope;
if (!is_array($scope)) $scope = &$GLOBALS;
$origin = $var;
$var = $checker = "very_weird_value#".rand()."#isnt_it";
$vname = false;
foreach ($scope as $key => $value){
if ($value === $checker){ $vname = "\$".$key; }
if (is_array($value) && $key!="GLOBALS"){
if ($pfad=aver($var,$value)){
$vname = "\$${key}[\"". implode("\"][\"",$pfad)."\"]";
}
}
if (is_object($value)){
if ($pfad=aver($var,get_object_vars($value))){
if (sizeof($pfad)<2) $vname = "\$${key}->".$pfad[0];
else{
$vname ="\$${key}->".$pfad[0];
$vname.="[\"".implode("\"][\"", array_slice($pfad,1))."\"]";
}
}
}
if ($vname) break;
}
$var = $origin;
if ($_SERVER["SERVER_NAME"] && !isset($_SERVER["TERM"])) echo "<pre>";
if ($vname){
echo $vname;
if ($label) echo " #" . $label . "# ";
else echo ": ";
}else{
if ($label) echo "$label: ";
}
print_r($var);
if ($_SERVER["SERVER_NAME"] && !isset($_SERVER["TERM"])) echo "</pre>";
}
function aver($needle,$haystack) { // array value exists recursive
foreach($haystack as $key=>$val) {
if(is_array($val) && $needle != $val && $key != "GLOBALS") {
if($foo=aver($needle,$val)) return array_merge(array($key),$foo);
}elseif($val === $needle) return array($key);
}
return false;
}
?>
[#42] SaWey @ localdomain [2007-01-15 11:44:46]
I've seen a lot of tries to give an easy way to output the "print_r" info in a decent way in you favorite browser.
Here's mine:
echo ("<pre>");
print_r("-->here goes your data to output<--");
echo ("<pre>");
I personaly think this is the easyest way.
Grz
[#43] Dmitry Kochin <dco at mail dot ru> [2006-09-08 01:20:12]
Sometimes print_r produces large output, especially when the data hierarchy is too deep. It is very difficult to analyze the dump about 1Mb length.
It would be great to have some way to fold arrays and objects and to look deeper into hierarchy only on demand.
Here is the solution. Just pass the print_r output to debug_var function:
debug_var('title', print_r($var, true));
and it will produce nice html with folding option.
<?php
ob_start();
?>
Locals: Array
(
[arr] => Array
(
[0] => Bon Object
(
[n] => id
[v] => 1
[dv] =>
[dn] =>
)
)
[b] => Bon Object
(
[n] => id
[v] => 1
[dv] =>
[dn] =>
)
[k] => 0
[row] => Array
(
[aid] => 1
[bonus] => spell.id: 125;
[req] =>
[brcache] =>
[auto] => 0
)
[sp] =>
)
<?php
$str = ob_get_contents();
ob_end_clean();
debug_var('locals', $str);
function debug_var($name,$data)
{
$captured = preg_split("/\r?\n/",$data);
print "<script>function toggleDiv(num){
var span = document.getElementById('d'+num);
var a = document.getElementById('a'+num);
var cur = span.style.display;
if(cur == 'none'){
a.innerHTML = '-';
span.style.display = 'inline';
}else{
a.innerHTML = '+';
span.style.display = 'none';
}
}</script>";
print "<b>$name</b>\n";
print "<pre>\n";
foreach($captured as $line)
{
print debug_colorize_string($line)."\n";
}
print "</pre>\n";
}
function next_div($matches)
{
static $num = 0;
++$num;
return "$matches[1]<a id=a$num href=\"javascript: toggleDiv($num)\">+</a><span id=d$num style=\"display:none\">(";
}
function debug_colorize_string($string)
{
$string = preg_replace("/\[(\w*)\]/i", '[<font color="red">$1</font>]', $string);
$string = preg_replace_callback("/(\s+)\($/", 'next_div', $string);
$string = preg_replace("/(\s+)\)$/", '$1)</span>', $string);
$string = str_replace('Array','<font color="blue">Array</font>',$string);
$string = str_replace('=>','<font color="#556F55">=></font>',$string);
return $string;
}
?>
This example uses ideas from this article:
http://www.zend.com/zend/tut/tutorial-DebugLib.php
[#44] ohira (atto) web. de [2006-04-13 07:01:05]
Bases on thbley?s sript i use this one to log some actions.
It will return a tabbed like string which you can output or whatever.
Input fields like "Password" will not be shown.
<?php
function print_r_string($arr,$first=true,$tab=0)
{
$output = "";
$tabsign = ($tab) ? str_repeat(' ',$tab) : '';
if ($first) $output .= "<pre><br>\n";
foreach($arr as $key => $val)
{
switch (gettype($val))
{
case "array":
$output .= $tabsign."[".htmlspecialchars($key)."] = array(".count($val).")<br>\n".$tabsign."(<br>\n";
$tab++;
$output .= print_r_string($val,false,$tab);
$tab--;
$output .= $tabsign.")<br>\n";
break;
case "boolean":
$output .= $tabsign."[".htmlspecialchars($key)."] bool = '".($val?"true":"false")."'<br>\n";
break;
case "integer":
$output .= $tabsign."[".htmlspecialchars($key)."] int = '".htmlspecialchars($val)."'<br>\n";
break;
case "double":
$output .= $tabsign."[".htmlspecialchars($key)."] double = '".htmlspecialchars($val)."'<br>\n";
break;
case "string":
$output .= $tabsign."[".htmlspecialchars($key)."] string = '".((stristr($key,'passw')) ? str_repeat('*', strlen($val)) : htmlspecialchars($val))."'<br>\n";
break;
default:
$output .= $tabsign."[".htmlspecialchars($key)."] unknown = '".htmlspecialchars(gettype($val))."'<br>\n";
break;
}
}
if ($first) $output .= "</pre><br>\n";
return $output;
}
echo print_r_string(array($_POST,$_GET)); // for Example
?>
[#45] reinder at fake-address dot com [2006-01-31 09:09:36]
I always use this function in my code, because most of my functions return an Array or Boolean :
<?php
function printr ( $object , $name = '' ) {
print ( '\'' . $name . '\' : ' ) ;
if ( is_array ( $object ) ) {
print ( '<pre>' ) ;
print_r ( $object ) ;
print ( '</pre>' ) ;
} else {
var_dump ( $object ) ;
}
}
?>
( print_r gives no output on FALSE and that can be annoying! )
[#46] thbley at gmail dot com [2005-11-16 12:10:24]
Here is a print_r that produces xml:
(now you can expand/collapse the nodes in your browser)
<?php
\n<data>\n";
header('Content-Type: text/xml; charset=UTF-8');
echo print_r_xml($some_var);
function print_r_xml($arr,$first=true) {
$output = "";
if ($first) $output .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
foreach($arr as $key => $val) {
if (is_numeric($key)) $key = "arr_".$key; // <0 is not allowed
switch (gettype($val)) {
case "array":
$output .= "<".htmlspecialchars($key)." type='array' size='".count($val)."'>".
print_r_xml($val,false)."</".htmlspecialchars($key).">\n"; break;
case "boolean":
$output .= "<".htmlspecialchars($key)." type='bool'>".($val?"true":"false").
"</".htmlspecialchars($key).">\n"; break;
case "integer":
$output .= "<".htmlspecialchars($key)." type='integer'>".
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
case "double":
$output .= "<".htmlspecialchars($key)." type='double'>".
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
case "string":
$output .= "<".htmlspecialchars($key)." type='string' size='".strlen($val)."'>".
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
default:
$output .= "<".htmlspecialchars($key)." type='unknown'>".gettype($val).
"</".htmlspecialchars($key).">\n"; break;
}
}
if ($first) $output .= "</data>\n";
return $output;
}
?>
[#47] warhog at warhog dot net [2005-08-11 17:01:13]
For very long arrays I have written a little function which formats an array quite nice and uses javascript for browsing it like a tree. The function is very customizable with the $style parameter.
For me it's of great use for browsing large array's, for example when those are used in language-files in some script and so on. It may even be used in "real" scripts for the "real" front-end, cause the tree can very easily be styled (look at the function or the outputted source and you'll see what i mean).
Here's the function:
<?php
function print_r_html($arr, $style = "display: none; margin-left: 10px;")
{ static $i = 0; $i++;
echo "\n<div id=\"array_tree_$i\" class=\"array_tree\">\n";
foreach($arr as $key => $val)
{ switch (gettype($val))
{ case "array":
echo "<a onclick=\"document.getElementById('";
echo array_tree_element_$i."').style.display = ";
echo "document.getElementById('array_tree_element_$i";
echo "').style.display == 'block' ?";
echo "'none' : 'block';\"\n";
echo "name=\"array_tree_link_$i\" href=\"#array_tree_link_$i\">".htmlspecialchars($key)."</a><br />\n";
echo "<div class=\"array_tree_element_\" id=\"array_tree_element_$i\" style=\"$style\">";
echo print_r_html($val);
echo "</div>";
break;
case "integer":
echo "<b>".htmlspecialchars($key)."</b> => <i>".htmlspecialchars($val)."</i><br />";
break;
case "double":
echo "<b>".htmlspecialchars($key)."</b> => <i>".htmlspecialchars($val)."</i><br />";
break;
case "boolean":
echo "<b>".htmlspecialchars($key)."</b> => ";
if ($val)
{ echo "true"; }
else
{ echo "false"; }
echo "<br />\n";
break;
case "string":
echo "<b>".htmlspecialchars($key)."</b> => <code>".htmlspecialchars($val)."</code><br />";
break;
default:
echo "<b>".htmlspecialchars($key)."</b> => ".gettype($val)."<br />";
break; }
echo "\n"; }
echo "</div>\n"; }
?>
The function as it is now does not support the $return parameter as print_r does and will create an endless loop like print_r did in php-versions < 4.0.3 when there is an element which contains a reference to a variable inside of the array to print out :-/
I've tested it with PHP 5.0.6 and PHP 4.2.3 - no problems except those already mentioned.
please e-mail me if you've got a solution for the problems i've mentioned, i myself are not able to solve them 'cause i don't know how the hell i can find out whether a variable is a reference or not.
[#48] nicky dot weber at siner dot de [2005-06-11 02:13:18]
Print arrays formatted for a browser easily:
<?php
function print_html_r( $aData ) {
echo nl2br( eregi_replace( " ", " ", print_r( $data, TRUE ) ) );
}
?>
[#49] general at NOSPAMbugfoo dot com [2005-01-20 13:23:18]
You can't use print_r($var, TRUE) inside a function which is a callback from ob_start() or you get the following error:
Fatal error: print_r(): Cannot use output buffering in output buffering display handlers